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

Val*_*ron 23 c++ unix linux pthreads

以下程序显示我们可以使用return()或pthread_exit()返回可用于pthread_join()的状态变量的void*变量.

(1)是否应优先使用一个而不是另一个?

(2)为什么使用return()有效?通常我们会想到返回将值放在堆栈上但是由于线程已经完成,堆栈应该消失.或者堆栈是否在pthread_join()之后才被销毁?

(3)在你的工作中,你是否看到很多地方变量的使用?我看到90%的代码看起来只是NULL状态参数.因为通过void*ptr改变的任何东西已经反映在调用线程中,所以返回它似乎没什么意义.返回的任何新的void*ptr都必须指向由开始线程进行malloc化的东西,这使得接收线程有责任处理它.我认为状态变量是无意义的,我错了吗?

#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;

}
Run Code Online (Sandbox Code Playgroud)

输出:

before 10 10 Hello
after task1 35 5.5 Goodbye
after task2 10 10 World
Run Code Online (Sandbox Code Playgroud)

Ant*_*ams 32

(1)在C++代码中,using return使得堆栈被展开并且局部变量被破坏,而pthread_exit只能保证调用注册的取消处理程序pthread_cancel_push().在某些系统上,这种机制也会导致调用C++局部变量的析构函数,但这不能保证可移植代码 - 请查看您的平台文档.

此外,in main(),return将隐式调用exit(),从而终止程序,而pthread_exit()只是终止线程,程序将保持运行,直到所有线程终止或一些线程调用exit(),abort()或另一个终止程序的函数.

(2)return因为POSIX规范这样说,所以使用了作品.返回的值存储在pthread_join()可以检索它的位置.线程使用的资源在pthread_join()被调用之前不会被回收.

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

  • 关于 (1), pthread_exit 不会立即终止线程,它首先运行取消处理程序。至少 NPTL/g++ 对取消处理程序和 C++ dtor 使用相同的机制,因此在这种情况下 pthread_exit 确实会展开堆栈。同样,OpenVMS pthread_exit/thread 取消会展开堆栈并运行 C++ dtor。您可能应该查看有关 pthread_exit 和堆栈展开行为的特定 pthread 实现的手册。 (2认同)

Jen*_*edt 6

我认为,returnstart_routine最好的,因为它确保调用堆栈是正常展开.

这对于C而言比C++更重要,因为它没有在初步退出后清理混乱的析构魔法.因此,您的代码应该遍历调用堆栈上的例程的所有最后部分以执行frees等.

为什么这个有效,这很简单

如果start_routine返回,则效果应该像使用start_routine的返回值作为退出状态对pthread_exit()进行隐式调用一样

根据我的个人经验,我倾向于不使用终止线程的状态.这就是我经常启动线程的原因detached.但这应该在很大程度上取决于应用程序,当然不能推广.