2016-11-08 13 views
1

Прошел год или около того, так как я играл с pthreads из класса ОС, и я пытался вернуться в него просто для удовольствия. Ниже приведен код моего простого упражнения на перенос, который я запускаю с online source. Меня беспокоит то, что в руководстве говорится, что выход должен быть:Вызов потоков до печати, но печать выполняется перед потоками

Thread 1 
Thread 2 
pthread_create() for thread 1 returns: 0 
pthread_create() for thread 2 returns: 0 

, что имеет смысл для меня. Но я получаю

pthread_create() for thread 1 returns: 0 
pthread_create() for thread 2 returns: 0 
Thread 1 
Thread 2 

pthread1.c

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

void *print_message_function(void *ptr); 

main() 
{ 
    pthread_t thread1, thread2; 
    const char *message1 = "Thread 1"; 
    const char *message2 = "Thread 2"; 
    int iret1, iret2; 

    iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1); 

    if(iret1) 
    { 
     fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1); 
     exit(EXIT_FAILURE); 
    } 

    iret2 = pthread_create(&thread2, NULL, print_message_function, (void*) message2); 

    if(iret2) 
    { 
     fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2); 
     exit(EXIT_FAILURE); 
    } 

    printf("pthread_create() for thread 1 returns: %d\n",iret1); 
    printf("pthread_create() for thread 2 returns: %d\n",iret2); 


    pthread_join(thread1, NULL); 
    pthread_join(thread2, NULL); 

    exit(EXIT_SUCCESS); 

void *print_message_function(void *ptr) 
{ 
    char *message; 
    message = (char *) ptr; 
    printf("%s \n", message); 
} 
+1

Похоже, что ваш урок неправильный. Сообщения могут отображаться в любом порядке или даже вкраплены. –

+1

Новый поток может, но не всегда, начинать работу до возвращения pthread_create(). Итак, вы можете получить управление обратно в main() перед началом каждого потока или после. Эта непредсказуемость означает, что операторы отображения могут отображаться в другом порядке для ответа на учебник. –

+0

опубликованный код не скомпилирован! При компиляции всегда включайте все предупреждения, затем устанавливайте эти предупреждения. (для 'gcc', при минимальном использовании:' -Wall -Wextra -pedantic' Я также использую: '-Wconversion -std = gnu99') 1) для функции' main() 'существует только две действующие сигнатуры:' int main (void) 'и' int main (int argc, char * argv []) 'Обратите внимание, что оба имеют возвращаемый тип' int' 2), функция 'main()' не имеет окончательной замыкающей скобки '}', 3) функция: 'print_message_function()' имеет возвращаемый тип 'void *', но отсутствует фактический оператор 'return'. – user3629249

ответ

1

Это называется состояние гонки.

Возможно, что после создания потока1 планировщик scheduler планирует функцию thread1 first1, тогда возможно, что функция потока выполнит сначала, а затем придет ваш основной() отпечаток.

В моей системе, когда я запускаю вашу программу.

[email protected]:~$ ./a.out 
pthread_create() for thread 1 returns: 0 
pthread_create() for thread 2 returns: 0 
Thread 2 
Thread 1 
[email protected]:~$ ./a.out 
pthread_create() for thread 1 returns: 0 
pthread_create() for thread 2 returns: 0 
Thread 1 
Thread 2 
1

Ознакомьтесь с учебным пособием. Кажется, что есть ошибка: код и его результат просто не совпадают (код о коде возврата от pthread_create и распечатать это код возврата нити, который недоступен, поскольку вызовы pthread_join выполнены с NULL в качестве второго параметра, а также print_message_function отсутствия возвращения ничего толкового)

Try сна (0); перед тем если (iret2) для удовольствия ...

1

Порядок выполнения зависит от планирования OS algorithm.Hence, любой один либо нить или функция, создающая поток может получить по расписанию (в зависимости от планирования ОС алгоритм) ,