2016-01-31 4 views
0

Я пишу программу на C с использованием Pthreads, которая создает дочерний поток. После создания дочернего потока родительский поток должен вывести два сообщения: «parent: begin», затем он должен напечатать «parent: done». То же самое для дочернего потока «child: begin» и «child: done». Я должен убедиться, что основной поток печатает свое второе сообщение до того, как порожденный (дочерний) поток. Я должен выполнить его, но он печатает только в неправильном порядке. Я предполагаю, что должен использовать флаги. Любая помощь будет оценена по достоинству.Pthread in C basic print

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


volatile int done = 0; 

void *child(void *arg) { 
printf("child\n"); 
done = 1; 
printf("child:done"); 
return NULL; 
} 

int main(int argc, char *argv[]) { 
printf("parent: begin\n"); 
pthread_t c; 
pthread_create(&c, NULL, child, NULL); // create child 
while (done == 0); // spin 
printf("parent: end\n"); 
return 0; 
} 
+0

Ваша детская нить только испускает одно сообщение. – uselpa

+0

Лучше всего это сделать с семейством системных вызовов ['wait'] (http://linux.die.net/man/2/wait) вместо цикла занятости в родительском. – kaylum

+0

Спасибо, я обновил код, и я хотел бы добиться того, чтобы основной поток печатал его второе сообщение до появления порожденного (дочернего) потока. –

ответ

2

Если вы хотите, чтобы родитель для печати done первый, то вы должны иметь спина ребенка нить, пока родитель не будет сделано. (Прямо сейчас родитель спины ждет ребенка.) Вы должны также использовать pthread_join, чтобы убедиться, что ребенок делается перед основными возвратов резьбы:

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


volatile int done = 0; 

void *child(void *arg) { 
    printf("child: begin\n"); 
    while (done == 0); // spin 
    printf("child: done\n"); 
    return NULL; 
} 

int main(int argc, char *argv[]) { 
    printf("parent: begin\n"); 
    pthread_t c; 
    pthread_create(&c, NULL, child, NULL); // create child 
    printf("parent: done\n"); 
    done = 1; 
    pthread_join(c, NULL); 
    return 0; 
} 

На моей машине я получаю этот выход:

parent: begin 
parent: done 
child: begin 
child: done 
+0

Благодарим вас за четкий код и объяснение! –

+1

Это не гарантирует, что ребенок: начало не будет напечатано перед родителем: сделано. – 2501

+1

@ 2501 - Это правда, но исходя из критериев в вопросе, я думаю, что имеет значение только «сделанная» часть ...? Если нужно также заказать сообщения «child: begin», тогда 'printf (« child: begin \ n »);' следует перемещать после цикла вращения. – DaoWen

0

В настоящий момент done доступен без какой-либо синхронизации обоими потоками. Правильный способ - сигнализировать ребенку, что родитель завершил печать с использованием условной переменной. Это приводит к данным гонки.

Более того, основная() нить завершает выполнение до того. В этом случае весь процесс погибнет. Вы можете либо позвонить pthread_join(), либо просто выйти из основного потока с pthread_exit().

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

    pthread_cond_t cond=PTHREAD_COND_INITIALIZER; 
    pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 

    volatile int done = 0; 

    void *child(void *arg) { 
     printf("child\n"); 
     pthread_mutex_lock(&mutex); 
     while(done == 0) 
     pthread_cond_wait(&cond, &mutex); 

     pthread_mutex_unlock(&mutex); 
     printf("child:done"); 
     return NULL; 
    } 

    int main(int argc, char *argv[]) { 
     printf("parent: begin\n"); 
     pthread_t c; 
     pthread_create(&c, NULL, child, NULL); // create child 

     pthread_mutex_lock(&mutex); 
     done = 1; 
     printf("parent: end\n"); 
     pthread_cond_signal(&cond); 
     pthread_mutex_unlock(&mutex); 

     pthread_exit(0); 
    } 
+0

Вопрос неоднозначен, поэтому я думаю, это не имеет значения. – 2501

+0

@ 2501 'Я должен удостовериться, что основной поток печатает его второе сообщение до того, как порожденный (дочерний) поток делает' <- Это, как я понимаю, говорит, что 'parent: end' (2nd msg) сначала печатается * перед * 'child: done' печатается. 'на данный момент: 1. parent: begin 2.child 3.child: done 4.parent: end.'<- OP считает это неправильным результатом, так как« parent: end »печатается как последний. Но OP явно принял ответ, который порождает нечто иное, которое не согласуется с моей интерпретацией. –

+0

Не грустно ли нам, что мы должны обсуждать то, о чем думает ОП, когда он отказывается отвечать на мои (теперь удаленные) комментарии, чтобы прояснить вопрос. Я обычно нажимаю close/downvote, и я думаю, что это правильный ответ, если OP не отвечает. – 2501