2015-11-27 5 views
0

Предполагается создать два потока и сообщить им свой идентификатор и назначенный им PID. Также выполняется некоторая базовая проверка ошибок.Является ли это слишком сложным кодом pthreads?

Есть ли более простой способ сделать это, не жертвуя проверкой ошибок?

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


pthread_t tid[1]; 

void* doSomething(void *arg) 
{ 
    int i = 0; 
    pthread_t id = pthread_self(); 
    const char* a[2]; 
    a[0]="Client(1)"; 
    a[1]="Server(2)"; 


    while (i<2) 
    { 

     if (pthread_equal(id,tid[i])) 
     printf("\n I'm the %s! My ID is: %ld. Our PID is= %d\n",a[i], (long int)&(tid[i]) , getpid()); 
     i++; 


    } 
    pthread_exit(0); 
} 

int main(void) 
{ 
    int i = 0; 
    int error; 

    while(i < 2) 
    { 
     error = pthread_create(&(tid[i]), NULL, &doSomething, NULL); 
     if (error != 0){ 
      printf("\n Error creating thread %d:[%s]",i+1, strerror(error)); 
      } 
    else{ 
     if(i==0){ 
      printf("\n Principal thread: Client thread (%i) created! Thread ID: %ld \n", i+1, (long int)&(tid[0])); 
      } 
     if(i==1){ 
      printf("\n Principal thread: Server thread (%i) created! Thread ID: %ldn", i+1, (long int)&(tid[1]));  
      } 

      i++; 
     } 
    } 
    if (pthread_join((tid[0]), NULL) == 0){ 
    printf ("\n Client has closed \n"); 
    } else {  
    printf ("\n Client closed with an error \n"); 
    } 
    if (pthread_join((tid[1]), NULL) == 0){ 
    printf ("\n Server has closed \n"); 
    }else{ 
    printf ("\nClient closed with an error \n"); 
    } 

    return 0; 
} 
+4

Не слишком сложный; просто вызывая неопределенное поведение. У вас есть 'if (pthread_equal (id, tid [i])), который будет обращаться к' tid [0] '(OK) и' tid [1] '(не в порядке), потому что вы определили' pthread_t tid [1] ; 'поэтому вы получаете доступ к массиву за пределами границ; кто знает, что происходит. Ваш код в 'main()' должен использовать цикл 'for' вместо цикла' while' со всеми запасными частями, разбросанными по всему коду. И он также не должен обращаться к массиву 'tid' за пределы. –

+0

Для кодового просмотра, пожалуйста, свяжитесь с [codereview.se], а не здесь. – fuz

+0

Я голосую, чтобы закрыть этот вопрос как не по теме, потому что это обзор кода, который принадлежит [codereview.se]. – fuz

ответ

1

Помимо непредсказуемого поведения упоминается в комментариях, вы можете также переписать код для не использовать цикл while и упростить функцию нити, такие как:

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

pthread_t tid[2]; 

void* doSomething(void *arg) 
{ 
    char *str = arg; 
    printf("\n I'm the %s! My ID is: %ld. Our PID is= %d\n", str, (long) pthread_self() , getpid()); 
    pthread_exit(0); 
} 

int main(void) 
{ 
    int i = 0; 
    int error; 
    const char *a[2] = {"Client (1)", "Client (2)" }; 

    for(i=0; i<2; i++) 
    { 
     error = pthread_create(&(tid[i]), NULL, &doSomething, (void*)a[i]); 
     if (error != 0) 
      printf("\n Error creating thread %d:[%s]",i+1, strerror(error)); 
     else 
      printf("\n Principal thread: Client thread (%i) created! Thread ID: %ld \n", i+1, (long int)&(tid[i])); 
    } 

    if (pthread_join((tid[0]), NULL) == 0){ 
    printf ("\n Client has closed \n"); 
    } else { 
    printf ("\n Client closed with an error \n"); 
    } 
    if (pthread_join((tid[1]), NULL) == 0){ 
    printf ("\n Server has closed \n"); 
    }else{ 
    printf ("\nClient closed with an error \n"); 
    } 

    return 0; 
} 

Вы можете также пропустите проверку ошибки на pthread_join(). В любом случае вы не можете сделать это, если это не сработает.

Кроме того, примечание литье pthread_t до long не гарантируется. Нет стандартного спецификатора формата, чтобы печатать его портативно. Если вы действительно обеспокоены этим, преобразуйте его в unsinged char* и распечатайте байты.

Смежные вопросы