我是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”但输出一个随机数。如何打印返回的值?
修改 根据第一个答案,问题是我返回指向局部变量的指针。返回/存储多个线程的变量的最佳做法是什么?全局哈希表?
提前致谢
答案 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)。你有价值而不会抛出丑陋的警告。