Linux pthread 启动函数中的 return() 与 pthread_exit()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3692591/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:08:09  来源:igfitidea点击:

return() versus pthread_exit() in pthread start functions

c++linuxunixpthreads

提问by ValenceElectron

The following program shows that we can use returnor pthread_exitto return a void*variable that is available to pthread_join's status variable.

以下程序显示我们可以使用returnpthread_exit返回一个void*可用于pthread_join的状态变量的变量。

  1. Should there be a preference for using one over the other?

  2. 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?

  3. 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. Since anything changed via the void*ptr is already reflected in the calling thread there doesn't seem much point to returning it. Any new void*ptr returned would have to point to something malloced by the start thread, which leaves the receiving thread with the responsibility to dispose of it. Am I wrong in thinking the status variable is semi-pointless?

  1. 是否应该优先使用一种而不是另一种?

  2. 为什么使用 return 有效?通常我们认为 return 将一个值放在堆栈上,但由于线程完成,堆栈应该消失。或者堆栈直到之后才被销毁pthread_join

  3. 在您的工作中,您是否看到状态变量的大量使用?我看到的 90% 的代码似乎只是将 status 参数设为 NULL。由于通过void*ptr更改的任何内容已经反映在调用线程中,因此返回它似乎没有多大意义。void*返回的任何新ptr 都必须指向malloc开始线程 ed 的内容,这让接收线程负责处理它。我认为状态变量是半无意义的,我错了吗?

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

采纳答案by Anthony Williams

(1) In C++ code, using returncauses the stack to be unwound and local variables destroyed, whereas pthread_exitis only guaranteed to invoke cancellation handlers registered with 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.

(1) 在 C++ 代码中, usingreturn会导致堆栈展开并销毁局部变量,而pthread_exit只能保证调用注册了pthread_cancel_push(). 在某些系统上,此机制还会导致调用 C++ 局部变量的析构函数,但这不能保证可移植代码 --- 检查您的平台文档。

Also, in main(), returnwill 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 returnworks because the POSIX specification says so. The returned value is stored in a place where pthread_join()can retrieve it. The resources used by the thread are not reclaimed until pthread_join()is called.

(2) 使用return作品因为POSIX规范是这么说的。返回的值存储在pthread_join()可以检索它的地方。线程使用的资源在pthread_join()被调用之前不会被回收。

(3) I never use the return value of a thread in raw POSIX threads. 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.

(3) 我从不使用原始 POSIX 线程中线程的返回值。但是,我倾向于使用更高级别的工具,例如 Boost 线程库,以及最近的 C++0x 线程库,它们提供了在线程之间传输值的替代方法,例如期货,从而避免了与内存管理相关的问题暗示。

回答by Jens Gustedt

I think that returnfrom the start_routineis preferable, because it ensures that the call stack is properly unwound.

我认为returnfromstart_routine是可取的,因为它确保调用堆栈正确展开。

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. So your code should go through all final parts of routines on the call stack to do frees and alike.

这对 C 来说比 C++ 更重要,因为它没有在初步退出后清理混乱的析构函数魔法。所以你的代码应该通过调用堆栈上例程的所有最终部分来执行frees 等。

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. But this should depend much on the application and is certainly not generalizable.

根据我的个人经验,我倾向于不经常使用终止线程的状态。这就是为什么我经常启动线程detached。但这应该在很大程度上取决于应用程序,并且肯定是不可推广的。