在pthread中返回void指针



我刚刚开始用pthreads学习C++中的多线程。我正在使用以下代码:

struct ArgT{
int a;
int b;
ArgT(int a, int b)
: a(a), b(b)
{}
ArgT()
:a(0), b(0)
{}
};
void* worker(void* arg)
{
ArgT* myArg = (ArgT*) arg;
int* result = new int;
*result = myArg->a + myArg->b;
std::cout << "(void*)result: " << (void*) result << std::endl;
return (void*)result;
}
int main()
{
ArgT mainArg(2,3);
pthread_t p;
int* main_result;
pthread_create(&p, NULL, worker, (void*)&mainArg);
pthread_join(p, (void**)&main_result); //??
std::cout << "main_result: " << main_result << std::endl; 
std::cout << "&main_result: "<< &main_result << std::endl;
printf("nResult = %dn", *main_result);
delete main_result;
return 0;
}

代码的输出如下

(void*)result: 0x7f07ac0008c0
main_result: 0x7f07ac0008c0
&main_result: 0x7fffb1aa0588
Result = 5

我的问题是pthread_join()接受void**作为第二个参数,它基本上是地址的地址。而我们在worker()函数中返回类型为void*的地址。这两种类型如何兼容?

pthread_join()获取指针变量的地址。该变量将接收线程返回的指针值。它实际上也在做同样的事情:

void doIt(void (*f)(), void** ptr)
{
*ptr = f();
}
void* func()
{
return ...; 
}
int main()
{
void *ptr;
doIt(func, &ptr);
// ptr holds whatever func() returns...
}

这两种类型如何兼容?

void**间接通过时,结果是类型为void*的左值


您的程序有未定义的行为。这里有一个正确的方法:

void* void_main_result;
pthread_join(p, &void_main_result);
int* int_main_result = static_cast<int*>(void_main_result);
std::cout << "nResult = " << *int_main_result;

您可以通过在参数中分配结果来避免动态分配。这样就不需要返回值:

struct ArgRet {
ArgT args;
int ret;
} mainArg;
pthread_create(&p, NULL, worker, &mainArg);
std::cout << "nResult = " << mainArg.ret;
// in worker
ArgRet* myArg = static_cast<ArgRet*>(arg);
myArg->ret = myArg->args.a + myArg->args.b;
return arg; // or nullptr; doesn't really matter

使用std::thread而不是pthreads 的主要优势是什么

std::thread适用于所有C++(11或更高版本(实现。pthreads只适用于POSIX系统。std::thread的API也更容易使用,因为它是用C++而不是C编写的。


p.S.将指针转换为void*是隐含的。我建议不要使用C样式强制转换。

最新更新