简体   繁体   中英

C Pthreads - Parent/Child process

I've written a C program that creates a child thread. After creating the child thread, the parent thread should output two messages. The first being "I am the parent" and the second "The parent is done". The same should occur for the child thread "I am the child" and "The child is done". However I want to make sure, the second message of the child is always done before the second message of the parent. How can I achieve this in my code below?

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

int status = 0;

void *print_child(void *arg)
{

    while (status == 0)
    {
        printf("Signal hasn't changed..\n");
        sleep(1);

    }
    printf("The child has started...\n");
    printf("The child is done! \n ");
}

int main()
{
    pthread_t child;
    pthread_create(&child, NULL, &print_child, NULL);

    sleep(2);
    printf("The parent has started...\n");
    printf("The parent is done! \n");

    status++;

    if (pthread_join(child, NULL))
    {
        printf("ERROR");
        exit(1);
    }
}

Once a thread created it process independently and act like a separate process from the main thread. In your case you are joining the child thread after the statement printf("The parent is done! \\n"); . It not necessary that operating system will complete the child thread first always. Hence your expected result might not meet always. put a long sleep statement just before statement printf("The parent is done! \\n"); and check but still not necessary that child will complete first.

The reason your code doesn't work is because you aren't making sure that the second printf in the parent thread is being executed before the second printf in the child thread.

A good option in this case would be to use mutexes. In this case, you can use a mutex to act as a 'guard' before the second printf, so the code will look something like this:

pthread_mutex_t print_lock;

...

In print_child:

// can only acquire after the parent releases, therefore guaranteeing that 
// the parent thread has already printed the second statement
pthread_mutex_lock(&print_lock); 
printf("The child is done! \n ");
pthread_mutex_unlock(&print_lock);

In main:

// lock it before the child thread is 
// started, therefore guaranteeing the parent will have initial ownership
pthread_mutex_lock(&print_lock); 
pthread_create(&child, NULL, &print_child, NULL);

sleep(2);
printf("The parent has started...\n");
printf("The parent is done! \n");
pthread_mutex_unlock(&print_lock);
...

Just put following line after printf("The parent has started...\\n"); and before printf("The parent is done! \\n"); :

status++;
if (pthread_join(child, NULL))
{
    printf("ERROR");
    exit(1);
}

So corrected code will be as following:

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

int status = 0;

void *print_child(void *arg)
{

    while (status == 0)
    {
        printf("Signal hasn't changed..\n");
        sleep(1);

    }
    printf("The child has started...\n");
    printf("The child is done! \n ");
}

int main()
{
    pthread_t child;
    pthread_create(&child, NULL, &print_child, NULL);

    sleep(2);
    printf("The parent has started...\n");
    status++;
    if (pthread_join(child, NULL))
    {
        printf("ERROR");
        exit(1);
    }
    printf("The parent is done! \n");
    return 0;
}

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