C语言 如何从C中的pthread线程返回一个值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2251452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to return a value from pthread threads in C?
提问by Petr Peller
I'am new to C and would like to play with threads a bit. I would like to return some value from a thread using pthread_exit()
我是 C 的新手,想玩一些线程。我想使用从线程返回一些值pthread_exit()
My code is as follows:
我的代码如下:
#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;
}
I would expect the program output "42\n" but it outputs a random number. How can I print the returned value?
我希望程序输出 "42\n" 但它输出一个随机数。如何打印返回值?
EDIT:According to first answers the problem is that I am returning pointer to local variable. What is the best practice of returning/storing variables of multiple threads? A global hash table?
编辑:根据第一个答案,问题是我正在返回指向局部变量的指针。返回/存储多线程变量的最佳实践是什么?全局哈希表?
Thanks in advance
提前致谢
采纳答案by Petr Peller
You are returning the address of a local variable, which no longer exists when the thread function exits. In any case, why call pthread_exit? why not simply return a value from the thread function?
您正在返回一个局部变量的地址,当线程函数退出时该变量不再存在。无论如何,为什么要调用 pthread_exit?为什么不简单地从线程函数返回一个值?
void *myThread()
{
return (void *) 42;
}
and then in main:
然后在主要:
printf("%d\n",(int)status);
If you need to return a complicated value such a structure, it's probably easiest to allocate it dynamically via malloc() and return a pointer. Of course, the code that initiated the thread will then be responsible for freeing the memory.
如果您需要返回这样一个结构体的复杂值,通过 malloc() 动态分配它并返回一个指针可能是最简单的。当然,启动线程的代码将负责释放内存。
回答by salsaman
Here is a correct solution. In this case tdata is allocated in the main thread, and there is a space for the thread to place its result.
这是一个正确的解决方案。在这种情况下,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;
}
回答by Steve Jessop
You've returned a pointer to a local variable. That's bad even if threads aren't involved.
您已经返回了一个指向局部变量的指针。即使不涉及线程,这也很糟糕。
The usual way to do this, when the thread that starts is the same thread that joins, would be to pass a pointer to an int, in a location managed by the caller, as the 4th parameter of pthread_create. This then becomes the (only) parameter to the thread's entry-point. You can (if you like) use the thread exit value to indicate success:
通常的做法是,当启动的线程与加入的线程相同时,将在调用者管理的位置传递一个指向 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;
}
If you absolutely have to use the thread exit value for a structure, then you'll have to dynamically allocate it (and make sure that whoever joins the thread frees it). That's not ideal, though.
如果您绝对必须为结构使用线程退出值,那么您将必须动态分配它(并确保加入线程的任何人都将其释放)。不过,这并不理想。
回答by Messa
I think you have to store the number on heap. The int retvariable was on stack and was destructed at the end of execution of function myThread.
我认为您必须将数字存储在堆上。该int ret变量在堆栈上,并在函数执行结束时被销毁myThread。
void *myThread()
{
int *ret = malloc(sizeof(int));
if (ret == NULL) {
// ...
}
*ret = 42;
pthread_exit(ret);
}
Don't forget to freeit when you don't need it :)
不需要free时不要忘记它:)
Another solution is to return the number as value of the pointer, like Neil Butterworth suggests.
另一种解决方案是将数字作为指针的值返回,就像 Neil Butterworth 建议的那样。
回答by Abhishek
#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);
}
回答by Jay
Question : What is the best practice of returning/storing variables of multiple threads? A global hash table?
问题:返回/存储多线程变量的最佳实践是什么?全局哈希表?
This totally depends on what you want to return and how you would use it? If you want to return only status of the thread (say whether the thread completed what it intended to do) then just use pthread_exit or use a return statement to return the value from the thread function.
这完全取决于您想要返回的内容以及您将如何使用它?如果你只想返回线程的状态(比如线程是否完成了它想要做的事情),那么只需使用 pthread_exit 或使用 return 语句从线程函数返回值。
But, if you want some more information which will be used for further processing then you can use global data structure. But, in that case you need to handle concurrency issues by using appropriate synchronization primitives. Or you can allocate some dynamic memory (preferrably for the structure in which you want to store the data) and send it via pthread_exit and once the thread joins, you update it in another global structure. In this way only the one main thread will update the global structure and concurrency issues are resolved. But, you need to make sure to free all the memory allocated by different threads.
但是,如果您想要更多用于进一步处理的信息,那么您可以使用全局数据结构。但是,在这种情况下,您需要使用适当的同步原语来处理并发问题。或者您可以分配一些动态内存(最好用于您想要存储数据的结构)并通过 pthread_exit 发送它,一旦线程加入,您就在另一个全局结构中更新它。这样只有一个主线程会更新全局结构,并发问题就解决了。但是,您需要确保释放不同线程分配的所有内存。
回答by Maurits Rijk
You are returning a reference to retwhich is a variable on the stack.
您正在返回对ret的引用,它是堆栈上的一个变量。
回答by Aditya
if you're uncomfortable with returning addresses and have just a single variable eg. an integer value to return, you can even typecast it into (void *) before passing it, and then when you collect it in the main, again typecast it into (int). You have the value without throwing up ugly warnings.
如果您对返回地址感到不舒服并且只有一个变量,例如。要返回的整数值,您甚至可以在传递它之前将其类型转换为 (void *),然后当您在 main 中收集它时,再次将其类型转换为 (int)。您拥有价值而不会抛出丑陋的警告。

