2015-10-31 3 views
0

Я попытался создать 3 потока, чтобы делать что-то и повторять в 2 раза, я ожидал, что все потоки скроются с помощью pthread_exit(NULL), но кажется, что вывод показывает только один раз и, возможно, потоки только создавались один раз ...?pthread_exit confusion in for loop

Я смущен использованием pthread_exit().

Правильно ли, что я могу уничтожить нить, используя этот ...?

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <sys/syscall.h> 
#include <sched.h> 

#define gettid() syscall(__NR_gettid) 

void *f1(void *a) 
{ 
    printf("f1\n"); 
    return NULL; 
} 

void *f2(void *a) 
{ 
    printf("f2\n"); 
    return NULL; 
} 

int main(int argc, char const *argv[]) 
{ 
    /* code */ 
    pthread_t t0,t1,t2; 
    int i ; 

    for (i = 0 ; i < 2 ; i++) 
    { 
     if (pthread_create(&t0,NULL,&f1,NULL)== -1) 
     printf("error 1\n"); 
     if (pthread_create(&t1,NULL,&f2,NULL)== -1) 
     printf("error 2\n"); 
     if (pthread_create(&t2,NULL,&f1,NULL)== -1) 
     printf("error 1\n"); 

     pthread_join(t0,NULL); 
     pthread_join(t1,NULL); 
     pthread_join(t2,NULL); 

     pthread_exit(NULL); 
    } 

    return 0; 
} 

ответ

1

выход показывает только один раз и, возможно, нить только создала один раз

код вызывает pthread_exit() после 1-я итерации в main()

for (i = 0 ; i < 2 ; i++) 
    { 
    ... 
    pthread_exit(NULL); 
    } 

поэтому нить, представленной main() выходов и дальнейшая итерация не выполняется, поэтому каждый вызов pthread_create() выполняется один раз.

Чтобы исправить это переместить вызов pthread_exit()послеfor -loop:

for (i = 0 ; i < 2 ; i++) 
    { 
    ... 
    } 

    pthread_exit(NULL); 

Я смущен от использования pthread_exit().

Правильно ли я могу уничтожить нить, используя этот ...?

pthread_exit() заканчивается вызывающий нить.

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

ресурсов волоска в освободились, для потока в состоянии ...

  • прилагаются по телефону pthread_join() на соответствующий PTHREAD-идентификатор.
  • отсоединен после прекращения нити, поэтому не требуется позвонить в pthread_join().

Чтобы отсоединить резьбу, используйте pthread_detach() на идентификаторе pthread резьбы, подлежащей отсоединению.


Также следует помнить, что для последних реализаций PTHREAD-API все функции возвращают код ошибки > 0.

Таким образом, вы должны изменить

if (pthread_create(&t0, NULL,&f1, NULL)== -1) 
    printf("error 1\n"); 

быть

if (0 != pthread_create(&t0, NULL,&f1, NULL)) 
    { 
    printf("error 1\n"); 
    } 

или даже лучше

int result; 

    ... 

    if (0 != (result = pthread_create(&t0, NULL, &f1, NULL))) 
    { 
    errno = result; 
    perror("pthread_create() failed"); 
    } 
+0

поэтому, если я выложу pthread_exit() из цикла, будет ли в моем случае создано 6 потоков (3 потока/цикл * 2 раза)? или я все еще получаю 3 потока, потому что второй цикл будет использовать тот же pthread_t? – KennyYang

+0

@KennyYang: 'pthread_create()' будет вызываться три раза на две итерации, то есть шесть раз. Вторая итерация, однако, не будет выполняться до того, как три потока, созданные первым, будут объединены, и это закончится. – alk

+0

Правильно ли, что вторая итерация использует один и тот же адрес первого итерационного потока, так что второй будет ждать, пока первый не остановится.? – KennyYang

1

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

+1

Этот ответ является неправильным. Конечно, вы можете называть 'pthread_exit' от' main', и если вы это сделаете, существует даже специальное правило. –

+0

@JensGustedt Хорошо, возможно, это технически разрешено, но почему бы вам это сделать? Очевидно, что оригинальный плакат не собирался ставить его в main(). – kcraigie

+1

Вы делаете это, если ваши потоки сами создают новые потоки, и у вас нет централизованного места, которое отслеживает все идентификаторы потоков. Тогда вы не можете присоединиться ко всем потокам просто потому, что не знаете их. Например, подумайте о динамически поддерживаемом пуле потоков. В такой ситуации вы должны позаботиться о том, чтобы 'main', когда он заканчивается, не убивает процесс и все остальные потоки с ним. Использование 'pthread_exit' - это * * способ сделать это. –

0

В вашем случае, так как основные вызовы его, основной поток прекратится.

pthread_exit() выход из потока, с помощью которого он звонит. Вы должны увидеть when-to-use-pthread-exit ?.