[英]return() versus pthread_exit() in pthread start functions
The following program shows that we can use return
or pthread_exit
to return a void*
variable that is available to pthread_join
's status variable. 以下程序显示我们可以使用
return
或pthread_exit
返回可用于pthread_join
状态变量的void*
变量。
Should there be a preference for using one over the other? 是否应优先使用一个而不是另一个?
Why does using return work? 为什么使用返回工作? Normally we think of return putting a value on the stack but since the thread is completed the stack should vanish.
通常我们会想到返回将值放在堆栈上但是由于线程已经完成,堆栈应该消失。 Or does the stack not get destroyed until after
pthread_join
? 或者堆栈是否在
pthread_join
之后才被销毁?
In your work, do you see much use of the status variable? 在您的工作中,您是否看到了很多状态变量的使用? It seems 90% of the code I see just NULLs out the status parameter.
我看到90%的代码看起来只是NULL状态参数。 Since anything changed via the
void*
ptr is already reflected in the calling thread there doesn't seem much point to returning it. 因为通过
void*
ptr改变的任何东西已经反映在调用线程中,所以返回它似乎没什么意义。 Any new void*
ptr returned would have to point to something malloc
ed by the start thread, which leaves the receiving thread with the responsibility to dispose of it. 返回的任何新的
void*
ptr都必须指向由启动线程进行malloc
编辑的东西,这使接收线程有责任处理它。 Am I wrong in thinking the status variable is semi-pointless? 我认为状态变量是无意义的,我错了吗?
Here is the code: 这是代码:
#include <iostream>
#include <pthread.h>
using namespace std;
struct taskdata
{
int x;
float y;
string z;
};
void* task1(void *data)
{
taskdata *t = (taskdata *) data;
t->x += 25;
t->y -= 4.5;
t->z = "Goodbye";
return(data);
}
void* task2(void *data)
{
taskdata *t = (taskdata *) data;
t->x -= 25;
t->y += 4.5;
t->z = "World";
pthread_exit(data);
}
int main(int argc, char *argv[])
{
pthread_t threadID;
taskdata t = {10, 10.0, "Hello"};
void *status;
cout << "before " << t.x << " " << t.y << " " << t.z << endl;
//by return()
pthread_create(&threadID, NULL, task1, (void *) &t);
pthread_join(threadID, &status);
taskdata *ts = (taskdata *) status;
cout << "after task1 " << ts->x << " " << ts->y << " " << ts->z << endl;
//by pthread_exit()
pthread_create(&threadID, NULL, task2, (void *) &t);
pthread_join(threadID, &status);
ts = (taskdata *) status;
cout << "after task2 " << ts->x << " " << ts->y << " " << ts->z << endl;
}
With output of: 输出:
before 10 10 Hello
after task1 35 5.5 Goodbye
after task2 10 10 World
(1) In C++ code, using return
causes the stack to be unwound and local variables destroyed, whereas pthread_exit
is only guaranteed to invoke cancellation handlers registered with pthread_cancel_push()
. (1)在C ++代码中,使用
return
会导致堆栈被展开并且局部变量被破坏,而pthread_exit
只能保证调用使用pthread_cancel_push()
注册的取消处理程序。 On some systems this mechanism will also cause the destructors for C++ local variables to be called, but this is not guaranteed for portable code --- check your platform documentation. 在某些系统上,这种机制也会导致调用C ++局部变量的析构函数,但这不能保证可移植代码 - 请查看您的平台文档。
Also, in main()
, return
will implicitly call exit()
, and thus terminate the program, whereas pthread_exit()
will merely terminate the thread, and the program will remain running until all threads have terminated or some thread calls exit()
, abort()
or another function that terminates the program. 另外,在
main()
, return
将隐式调用exit()
,从而终止程序,而pthread_exit()
只会终止该线程,程序将保持运行,直到所有线程都终止或某些线程调用exit()
, abort()
或终止程序的其他函数。
(2) The use of return
works because the POSIX specification says so. (2)
return
的使用是有效的,因为POSIX规范是这样说的。 The returned value is stored in a place where pthread_join()
can retrieve it. 返回的值存储在
pthread_join()
可以检索它的位置。 The resources used by the thread are not reclaimed until pthread_join()
is called. 在调用
pthread_join()
之前,不会回收线程使用的资源。
(3) I never use the return value of a thread in raw POSIX threads. (3)我从不在原始POSIX线程中使用线程的返回值。 However, I tend to use higher level facilities such as the Boost thread library, and more recently the C++0x thread library, which provide alternative means for transferring values between threads such as futures, which avoid the problems associated with memory management that you allude to.
但是,我倾向于使用更高级别的工具,例如Boost线程库,以及最近的C ++ 0x线程库,它提供了在诸如期货之类的线程之间传输值的替代方法,从而避免了与内存管理相关的问题。暗示。
I think that return
from the start_routine
is preferable, because it ensures that the call stack is properly unwound. 我认为从
start_routine
return
是更可取的,因为它确保调用堆栈被正确解开。
This is even more important for C than C++ since it doesn't have the destructor magic that cleans up the mess after preliminary exits. 这对于C而言比C ++更重要,因为它没有在初步退出后清理混乱的析构魔法。 So your code should go through all final parts of routines on the call stack to do
free
s and alike. 因此,您的代码应该遍历调用堆栈上的例程的所有最后部分,以执行
free
s等。
For why this works, this is simple 为什么这个有效,这很简单
If the start_routine returns, the effect shall be as if there was an implicit call to pthread_exit() using the return value of start_routine as the exit status
如果start_routine返回,则效果应该像使用start_routine的返回值作为退出状态对pthread_exit()进行隐式调用一样
For my personal experience I tend to not use the status of terminated threads much. 根据我的个人经验,我倾向于不使用终止线程的状态。 This is why I often have the threads started
detached
. 这就是我经常将线程
detached
。 But this should depend much on the application and is certainly not generalizable. 但这应该在很大程度上取决于应用程序,当然不能推广。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.