简体   繁体   English

pthread_exit vs posix线程中的返回

[英]pthread_exit vs return in posix thread

Here is my program just to find the difference between pthread_exit and return from a thread. 这是我的程序,只是为了找到pthread_exit和从线程返回之间的区别。

struct foo{
    int a,b,c,d;
    ~foo(){cout<<"foo destructor called"<<endl;}
};
//struct foo foo={1,2,3,4};
void printfoo(const char *s, const struct foo *fp)
{
    cout<<s;
    cout<<"struct at 0x"<<(unsigned)fp<<endl;
    cout<<"foo.a="<<fp->a<<endl;
    cout<<"foo.b="<<fp->b<<endl;
    cout<<"foo.c="<<fp->c<<endl;
    cout<<"foo.d="<<fp->d<<endl;
}
void *thr_fn1(void *arg)
{
    struct foo foo={1,2,3,4};
    printfoo("thread1:\n",&foo);
    pthread_exit((void *)&foo);
    //return((void *)&foo);
}
int main(int argc, char *argv[])
{
    int err;
    pthread_t tid1,tid2;
    struct foo *fp;
    err=pthread_create(&tid1,NULL,thr_fn1,NULL);
    if(err!=0)
            cout<<"can't create thread 1"<<endl;
    err=pthread_join(tid1,(void **)&fp);
    if(err!=0)
            cout<<"can't join with thread 1"<<endl;
    exit(0);
}

In "*thr_fn1" thread function I created an object foo. 在“* thr_fn1”线程函数中,我创建了一个对象foo。

According to the site pthread_exit vs. return when I exit the thread function "thr_fun1()" using "return((void *)&foo);" 根据站点pthread_exit与使用“return((void *)&foo)”退出线程函数“thr_fun1()”时返回; it should call the destructor for the object foo, but it should not call the destructor when I call "pthread_exit((void *)&foo);" 它应该调用对象foo的析构函数,但是当我调用“pthread_exit((void *)&foo)”时它不应该调用析构函数;“ to return to main from function "thr_fun1()". 从函数“thr_fun1()”返回main。

But in both the cases using "return((void *)&foo);" 但在两种情况下都使用“return((void *)&foo);” or "pthread_exit((void *)&foo);" 或“pthread_exit((void *)&foo);” the local object "foo" in function "thr_fun1()" is getting called. 调用函数“thr_fun1()”中的本地对象“foo”。

This is not the behaviour I guess. 这不是我猜的行为。 Destructor should be called only in "return((void *)&foo);" 应该只在“return((void *)&foo);”中调用析构函数。 case only. 仅限案例。

Please verify me if I am wrong? 如果我错了,请验证我?

Yes, that's right. 是的,这是正确的。 pthread_exit() immediately exits the current thread, without calling any destructors of objects higher up on the stack. pthread_exit()立即退出当前线程,而不调用堆栈上方对象的任何析构函数。 If you're coding in C++, you should make sure to either always return from your thread procedure, or only call pthread_exit() from one of the bottommost stack frames with no objects with destructors still alive in that frame or any higher frames; 如果您使用C ++进行编码,则应确保始终从线程过程return ,或者仅从最底层的堆栈帧之一调用pthread_exit() ,而没有具有析构函数的对象在该帧或任何更高的帧中仍然存活; otherwise, you will leak resources or cause other bad problems. 否则,您将泄漏资源或导致其他不良问题。

Your code has a serious problem. 您的代码存在严重问题。 Specifically, you're using a local variable as the exit value for pthread_exit(): 具体来说,您使用局部变量作为pthread_exit()的退出值:

void *thr_fn1(void *arg)
{
    struct foo foo={1,2,3,4};
    printfoo("thread1:\n",&foo);
    pthread_exit((void *)&foo);
    //return((void *)&foo);
}

Per the Pthreads spec , " After a thread has terminated, the result of access to local (auto) variables of the thread is undefined. " 根据Pthreads规范 ,“ 在线程终止后,线程的本地(自动)变量的访问结果是未定义的。

Therefore, returning the address of a stack-allocated variable from your thread function as the thread exit value (in your case, pthread_exit((void *)&foo) ) will cause problems for any code that retrieves and attempts to dereference this address. 因此,从线程函数返回堆栈分配变量的地址作为线程退出值(在您的情况下, pthread_exit((void *)&foo) )将导致任何检索并尝试取消引用此地址的代码出现问题。

pthread_exit() is throwing an exception which causes the stack to unwind and destructors to be called for locals. pthread_exit()抛出异常,导致堆栈展开,并为本地调用析构函数。 See https://stackoverflow.com/a/11452942/12711 for more details. 有关详细信息,请参阅https://stackoverflow.com/a/11452942/12711

The exception thrown is of type abi::__forced_unwind (from cxxabi.h ); 抛出的异常是abi::__forced_unwind类型(来自cxxabi.h ); an Internet search can give you more details. 互联网搜索可以为您提供更多详细信息。


note: as other answers/comments have mentioned, returning the address of a local wouldn't work anyway, but that is besides the point of the question. 注意:正如其他答案/评论所提到的那样,返回本地地址无论如何都不会起作用,但这也是问题的重点。 You get the same behavior regarding destructing foo if some other valid address (or the null pointer) is returned instead of &foo . 如果返回一些其他有效地址(或空指针)而不是&foo则会获得与描述foo相同的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM