如何从C中的pthread线程返回一个值?

时间:2010-02-12 11:34:00

标签: c pthreads

我是C的新手,想稍微玩一下线程。我想使用pthread_exit()

从线程中返回一些值

我的代码如下:

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

void *myThread()
{
   int ret = 42;
   pthread_exit(&ret);
}

int main()
{
   pthread_t tid;
   void *status;

   pthread_create(&tid, NULL, myThread, NULL);
   pthread_join(tid, &status);

   printf("%d\n",*(int*)status);   

   return 0;
}

我希望程序输出“42 \ n”但输出一个随机数。如何打印返回的值?

修改 根据第一个答案,问题是我返回指向局部变量的指针。返回/存储多个线程的变量的最佳做法是什么?全局哈希表?

提前致谢

8 个答案:

答案 0 :(得分:42)

您正在返回局部变量的地址,当线程函数退出时,该地址变量不再存在。无论如何,为什么要调用pthread_exit?为什么不简单地从线程函数返回一个值?

void *myThread()
{
   return (void *) 42;
}

然后在main:

printf("%d\n",(int)status);   

如果需要返回一个复杂的值这样的结构,最简单的方法是通过malloc()动态分配它并返回一个指针。当然,启动该线程的代码将负责释放内存。

答案 1 :(得分:25)

您已返回指向局部变量的指针。即使不涉及线程,这也很糟糕。

执行此操作的常用方法是,当启动的线程是连接的同一个线程时,将在调用者管理的位置传递指向int的指针,作为pthread_create的第4个参数。然后它成为线程入口点的(唯一)参数。您可以(如果您愿意)使用线程退出值来表示成功:

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

int something_worked(void) {
    /* thread operation might fail, so here's a silly example */
    void *p = malloc(10);
    free(p);
    return p ? 1 : 0;
}

void *myThread(void *result)
{
   if (something_worked()) {
       *((int*)result) = 42;
       pthread_exit(result);
   } else {
       pthread_exit(0);
   }
}

int main()
{
   pthread_t tid;
   void *status = 0;
   int result;

   pthread_create(&tid, NULL, myThread, &result);
   pthread_join(tid, &status);

   if (status != 0) {
       printf("%d\n",result);
   } else {
       printf("thread failed\n");
   }

   return 0;
}

如果你必须使用结构的线程退出值,那么你必须动态分配它(并确保加入线程的人释放它)。但这并不理想。

答案 2 :(得分:21)

这是一个正确的解决方案。在这种情况下,tdata在主线程中分配,并且线程有一个空间来放置其结果。

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

typedef struct thread_data {
   int a;
   int b;
   int result;

} thread_data;

void *myThread(void *arg)
{
   thread_data *tdata=(thread_data *)arg;

   int a=tdata->a;
   int b=tdata->b;
   int result=a+b;

   tdata->result=result;
   pthread_exit(NULL);
}

int main()
{
   pthread_t tid;
   thread_data tdata;

   tdata.a=10;
   tdata.b=32;

   pthread_create(&tid, NULL, myThread, (void *)&tdata);
   pthread_join(tid, NULL);

   printf("%d + %d = %d\n", tdata.a, tdata.b, tdata.result);   

   return 0;
}

答案 3 :(得分:4)

我认为你必须将数字存储在堆上。 int ret变量在堆栈上,在函数myThread执行结束时被破坏。

void *myThread()
{
       int *ret = malloc(sizeof(int));
       if (ret == NULL) {
           // ...
       }
       *ret = 42;
       pthread_exit(ret);
}

当你不需要时,不要忘记free:)

另一个解决方案是将数字作为指针的值返回,就像Neil Butterworth建议的那样。

答案 4 :(得分:2)

您将返回对 ret 的引用,该引用是堆栈中的变量。

答案 5 :(得分:2)

#include<stdio.h>
#include<pthread.h>
void* myprint(void *x)
{
 int k = *((int *)x);
 printf("\n Thread created.. value of k [%d]\n",k);
 //k =11;
 pthread_exit((void *)k);

}
int main()
{
 pthread_t th1;
 int x =5;
 int *y;
 pthread_create(&th1,NULL,myprint,(void*)&x);
 pthread_join(th1,(void*)&y);
 printf("\n Exit value is [%d]\n",y);
}  

答案 6 :(得分:1)

问题:返回/存储多个线程变量的最佳做法是什么?全局哈希表?

这完全取决于您想要返回的内容以及如何使用它?如果只想返回线程的状态(说明线程是否完成了它想要做的事情),那么只需使用pthread_exit或使用return语句从线程函数返回值。

但是,如果您想要更多信息用于进一步处理,那么您可以使用全局数据结构。但是,在这种情况下,您需要使用适当的同步原语来处理并发问题。或者你可以分配一些动态内存(最好是你想要存储数据的结构)并通过pthread_exit发送它,一旦线程加入,你就可以在另一个全局结构中更新它。这样,只有一个主线程将更新全局结构,并解决并发问题。但是,您需要确保释放由不同线程分配的所有内存。

答案 7 :(得分:0)

如果您对返回地址感到不舒服,并且只有一个变量,例如。要返回的整数值,您甚至可以在传递它之前将其强制转换为(void *),然后当您在main中收集它时,再次将其转换为(int)。你有价值而不会抛出丑陋的警告。