【问题标题】:How do I return a struct from a thread?如何从线程返回结构?
【发布时间】:2019-04-13 22:47:31
【问题描述】:

我正在尝试学习如何从线程返回一些值,但我没有成功。我在我的代码中考虑到我不能返回一个全局变量,所以我从malloc 获取内存,但我在pthread_join 中显然有问题。

#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>

struct DIRECCION{
    char street [20];
    int number;
}   ;



struct DIRECCION * pd = NULL;

void* show(void* dm){

    struct DIRECCION * di = (void*)dm;
    pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
    printf("\nHilo show\n");
    printf("Calle: %s\t",di->street);
    printf("Altura: %d\n",di->number);

    printf("Calle: ");
    scanf("%s",pd->street);
    printf("Altura: ");
    scanf("%d",&(pd->number));
    printf("me jui\n");


    return((void*)pd);
}



int main (void){

    pthread_t s_id;
    struct DIRECCION dm;
    struct DIRECCION  d ;


    printf("\nProceso\n");
    printf("Calle: ");
    scanf("%s",dm.street);
    printf("Altura: ");
    scanf("%d",&(dm.number));


    pthread_create( &s_id , NULL, (void*)&show, (void*)&dm);
    pthread_join( s_id , (void*)&d );

    printf("Calle: %s\t",(d.street));
    printf("Altura: %d\n",(d.number));
    free(pd);
    return 0;
}

【问题讨论】:

  • 欢迎来到 StackOverflow!请务必使用tour 并访问help center。你能解释一下你有什么样的“问题”吗?发布您获得的错误消息和输出,以及它们与预期的不同之处。
  • 谢谢,当我从 main 打印时,线程返回的结构不是我在线程中写的
  • 很高兴看到您有这么多答案。未来问题的注释:任何重要信息都应该在问题中,而不是在评论中。

标签: c linux pthreads


【解决方案1】:

第一步——去掉所有的演员表。你不需要它们,它们隐藏了你可能会从编译器那里得到的错误,这些错误会告诉你你做错了什么。

当您这样做时,您会立即看到问题在于您对pthread_join 的调用——当它需要void ** 时,您尝试使用struct DIRECCION * 调用它。要修复它,您需要传递一个void **,这意味着您需要一个void * 来获取地址:

void *tmp;
struct DIRECCION *d;
pthread_join( s_id , &tmp );
d = tmp;
... do stuff with d->whatever

【讨论】:

    【解决方案2】:

    在你的线程函数中你有:

    pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
    return((void*)pd);
    

    这就是说返回您分配的内存的地址。然后,在你的 main 函数中,

    struct DIRECCION  d ;
    pthread_join( s_id , (void*)&d );
    

    这就是说将线程函数返回的值写入存储d 的内存。换句话说,您写给d 的是struct DIRECCION*,而不是struct DIRECCION

    试试类似的东西

    #include<stdio.h>
    #include<stdlib.h>
    #include <pthread.h>
    
    struct DIRECCION{
      char street [20];
      int number;
    }   ;
    
    void* show(void* dm){
      struct DIRECCION * pd = NULL;
      struct DIRECCION * di = (void*)dm;
      pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
      printf("\nHilo show\n");
      printf("Calle: %s\t",di->street);
      printf("Altura: %d\n",di->number);
    
      printf("Calle: ");
      scanf("%s",pd->street);
      printf("Altura: ");
      scanf("%d",&(pd->number));
      printf("me jui\n");
    
      return((void*)pd);
    }
    
    int main (void){
      pthread_t s_id;
      struct DIRECCION dm;
      struct DIRECCION*  d ;
    
    
      printf("\nProceso\n");
      printf("Calle: ");
      scanf("%s",dm.street);
      printf("Altura: ");
      scanf("%d",&(dm.number));
    
    
      pthread_create( &s_id , NULL, (void*)&show, (void*)&dm);
      pthread_join( s_id , (void**)&d );
    
      printf("Calle: %s\t",(d->street));
      printf("Altura: %d\n",(d->number));
      free(d);
      return 0;
    }
    

    【讨论】:

    • 谢谢,它有效,但我不明白有什么区别,你能解释一下吗?
    • 您正在为结构分配一个指针(由malloc 返回的那个)。通过我所做的更改, d 是一个 pointer 而不是实际的结构,并且您正在将指针分配给指针。变化真的都在maind 更改为 struct DIRECCION*,printf 调用更改为 d-&gt;street 而不是 d.street(数字字段同上)。 d-&gt;street 的另一种写法是(*d).street
    【解决方案3】:

    show()中的代码是可以的,撇开

    • 所有这些转换,在 C 中完全没用。
    • 以及pd 是全局定义的事实

      struct DIRECCION * pd = NULL;
      
      void* show(void* dm)
      {
        ...
      

      这不是必需的。将pd本地定义为show()

      void* show(void* dm)
      {
        struct DIRECCION * pd = dm;
        ...
      

    main() 中,提取show() 返回的指针值的简洁方法是:

    int main(void)
    {
      ...
    
      {
        void * pv;
        pthread_join(s_id, &pv);
    
        /* Find the value inside pv here. */
      }
    

    如上所述,有两种可能继续从pthread_join()检索指针值:

    • 像这样使用指针值:

      int main(void)
      {
        struct DIRECCION * pd;
        ...
      
        {
          void * pv;
          pthread_join(s_id, &pv);
      
          pd = pv;
        }
      
        printf("Calle: %s\t", pd->street);
      
        ...
      
    • 取消引用指针值并将其指向的内容复制到合适的结构中(之后不需要它指向的内存,因此释放它以避免泄漏):

      int main(void)
      {
        struct DIRECCION d;
        ...
      
        {
          void * pv;
          pthread_join(s_id, &pv);
      
          d = *((struct DIRECCION *) pv); /* The only cast necessary in fact. */
      
          free(pv);  /* This frees what has been allocated in `show()`. */
        }
      
        printf("Calle: %s\t", d.street);
      
        ...
      

    请注意pthread_join()可能会失败,因此强烈建议测试它返回的失败值。

    如果pthread_join() 成功,它返回的指针值可能仍然是NULL,因此在取消引用指针值之前测试它是必不可少的。

    因此(尝试)从pthread_join() 中提取指针值的安全方法是:

    int main(void)
    {
      ...
    
      {
        void * pv;
        int result = pthread_join(s_id, &pv);
        if (0 != result)
        {
          fprintf("pthread_join() failed: %s\n", strerror(result));
          exit(EXIT_FAILURE); /* EXIT_x come with stdlib.h. */
        }
    
        if (NULL == pv)
        {
          /* Handle this case here or exit() as well. */
        }
        else
        {
          /* Use the value inside pv here. */
        }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-11
      • 2015-10-14
      • 1970-01-01
      • 2019-08-14
      • 1970-01-01
      • 2014-11-19
      • 2020-03-03
      • 1970-01-01
      相关资源
      最近更新 更多