简体   繁体   English

线程终止问题(C编程)

[英]thread termination issue (c programming)

I'm working on an application for Linux in C which uses multiple threads. 我正在使用C使用多个线程的Linux应用程序。 The threads which are spawned by the main function do most of the work, and therefore usually finish last. main函数产生的线程完成了大部分工作,因此通常最后完成。 I'm seeing some strange behavior, and I believe it's due to the main thread terminating before the spawned threads have a chance to finish their jobs. 我看到了一些奇怪的行为,并且我相信这是由于主线程在生成的线程有机会完成其工作之前终止。 Here's some sample code to illustrate what I'm talking about: 这是一些示例代码来说明我在说什么:

#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#define _GNU_SOURCE

#include <pthread.h>
#include <stdio.h>

void
my_cleanup(void *arg)
{
     printf("cleanup: %s\n", (char *)arg);
}


void *
thread_stuff(void *arg)
{
     printf("thread started\n");
     pthread_cleanup_push(cleanup, "running");
     if (arg)
          pthread_exit((void *)2);
     pthread_cleanup_pop(0);
     pthread_exit((void *)2);
}


int
main()
{
     int err;
     pthread_t tid1, tid2;

     err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
     err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);

     sleep(10);                 /* change the value here if you want */

     return SUCCESS;
}

When this code is run, the message from the cleanup function is printed twice, as it should be, but other times when it is run, I see the message printed only once sometimes, and other times I see it printed three times or not at all. 运行此代码时,清理函数中的消息应按应有的方式打印两次,但是有时运行时,我看到的消息有时仅打印一次,而有时我看到的消息却打印了三遍。所有。 You add in the sleep function in the main function to play with how long it takes the main function to terminate. 您可以在main函数中添加sleep函数,以播放main函数终止所需的时间。

What can I do to make the program run as it should? 我怎样做才能使程序正常运行? I suspect it has something to do with joining to the children, but I don't entirely understand the concept of a join or how to apply it to this situation. 我怀疑这与加入孩子有关,但我并不完全了解加入的概念或如何将其应用于这种情况。

Thanks in advance! 提前致谢!

Yes, you should "join" the threads. 是的,您应该“加入”线程。 "Joining" a thread simply means waiting until the thread has terminated. “加入”线程仅意味着等待直到线程终止。 In other words, you would do 换句话说,你会做

pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

to wait until both threads have terminated. 等待两个线程都终止。

Edit: What to do if you have a child thread which, in turn, creates a "grandchild" thread? 编辑:如果您有一个子线程,又创建了一个“孙子”线程,该怎么办? As a rule, whoever created the thread should wait for it to terminate ("join" it). 通常,创建线程的任何人都应等待线程终止(“加入”线程)。 So in this scenario, the child thread would call phtread_join on the grandchild thread, and the main thread would call join on the child thread. 因此,在这种情况下,子线程将在孙线程上调用phtread_join,而主线程将在子线程上调用join。

I think you want to run pthread_join on each of the threads when your main thread completes -- this makes the main thread stop until the given thread finishes running. 我认为您想在主线程完成时在每个线程上运行pthread_join ,这会使主线程停止直到给定线程完成运行。 Other threads can still complete first though, so running pthread_join on every thread will prevent the main thread from terminiating until all of the others have terminated. 但是其他线程仍然可以先完成,因此在每个线程上运行pthread_join将阻止主线程终止,直到所有其他线程都终止。

There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. 如果main()在未显式调用pthread_exit()的情况下在其产生的线程之前完成,则肯定存在问题。 All of the threads it created will terminate because main() is done and no longer exists to support the threads. 它创建的所有线程将终止,因为main()已完成,并且不再存在以支持线程。

By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done. 通过让main()显式调用pthread_exit()作为最后一件事,main()将被阻塞并保持活动状态以支持它创建的线程,直到完成。

int main()
    {
         int err;
         pthread_t tid1, tid2;

         err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
         err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);

         sleep(10);                 /* change the value here if you want */

         /* Add the pthread_exit */     
         pthread_exit(NULL);
         return SUCCESS;
    }

Refer for more info here 在这里参考更多信息

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

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