2010-11-11 12 views
0

這是一個非常簡單的多線程程序。它會創建兩個線程並運行。pthread程序的一些不可思議的結果

在線程中,它會將argv0複製到origname

第一次,origname是正確的。

但進入while循環後,origname將被sprintf損壞。

它將打印,如:

Hello World! It's me, thread #0 ./multithread 3!

origname 0 ./multithread 3!

origname內容爲sprintf參數。我不明白是什麼原因。任何人都可以幫忙

#include <pthread.h> 
#include <stdio.h> 
#define NUM_THREADS  2 
void sendstring(char *string) 
{ 
    printf("%s",string); 
} 
struct thread_data{ 
    int thread_id; 
    char *argv0; 
}; 

struct thread_data thread_data_array[NUM_THREADS]; 


void *PrintHello(void *parameter) 
{ 
    struct thread_data *childpara; 
    childpara = (struct thread_data *)parameter; 
    int i = 0; 
    char origname[20]; 
    strncpy(origname, childpara->argv0,strlen(childpara->argv0)); 
    origname[strlen(childpara->argv0)] = '\0'; 
    printf("init origname %s argv0 %s\n",origname, childpara->argv0); 

    while(1) 
    { 
      printf("origname %s\n",origname); 
      sleep(1); 
      char buffer[30]; 
      sprintf(buffer,"Hello World! It's me, thread #%ld %s %d!\n", childpara->thread_id, childpara->argv0, i++); 
      sendstring(buffer); 
    } 
    pthread_exit(NULL); 
} 

int main (int argc, char *argv[]) 
{ 
    pthread_t threads[NUM_THREADS]; 
    int rc; 
    long t; 
    for(t=0; t<NUM_THREADS; t++){ 
      thread_data_array[t].thread_id = t; 
      thread_data_array[t].argv0 = argv[0]; 
      rc = pthread_create(&threads[t], NULL, PrintHello,(void *) &thread_data_array[t]);  

      if (rc){ 
        printf("ERROR; return code from pthread_create() is %d\n", rc); 
        exit(-1); 
      } 
    } 
    pthread_exit(NULL); 
} 

回答

0

您的問題是從這一行來:

thread_data_array[t].argv0 = argv[0]; 

的argv被定義爲char **argv(同char *argv[]),由此的argv [0]是一個指針。因此,thread_data_array[t].argv0argv中數據的別名。

最後,這兩個線程共享相同的字符串,並且一切都搞砸了。不要問我什麼時候搞砸的確切細節,因爲當你這樣做的時候會有大量的事情發生,這取決於哪一行代碼在什麼時候運行。

您需要改用strcpy()。這樣,每個線程都有自己的副本,並且兩個線程不會互相混淆。

+0

這就是我想要的。我想用argv [0]作爲新創建線程的參數。我認爲這不是問題。我將這個指針的內容複製到origname,但不是指針。當我評論sprintf時,它工作正常。 – Zhongshu 2010-11-11 17:16:54

+0

您需要了解 - 您*不*複製內容。你只是在複製指針,這意味着兩個線程指向相同的內存空間。使用strcpy()。 – riwalk 2010-11-11 18:59:24

+0

另外,輸出中沒有信號量/障礙/互斥量,所以當你運行它時,兩個線程的輸出偶爾會被混淆。 – riwalk 2010-11-11 19:03:55

2

你的問題是緩衝區溢出。我數:

Hello World! It's me, thread #0 ./multithread 3! 

在超過40個字符,但你sprintf'ing它到一個30字節的緩衝區。發生這種情況後,所有投注都關閉。結果是未定義的。它可能會崩潰,它可能會造成奇怪的事情,它可能會製造一個納米機器人並將其發送給整個開發團隊購買咖啡。