简体   繁体   中英

thread termination issue (c programming)

I'm working on an application for Linux in C which uses multiple threads. The threads which are spawned by the main function do most of the work, and therefore usually finish last. 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.

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.

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

There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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