pthread_create()的一個錯誤示例


 

 1 //pthread_create()函數的錯誤示例
 2 //新建線程同時傳入線程號、線程號總和和消息
 3 #include <stdio.h>
 4 #include <pthread.h>
 5 #include <stdlib.h>
 6 #define NUM_THREADS     8
 7 
 8 void *PrintHello(void *threadid)
 9 {
10         int *id_ptr, taskid;
11         sleep(1);
12         id_ptr=(int *)threadid;
13         taskid=*id_ptr;
14         printf("Hello from thread %d\n", taskid);
15         pthread_exit(NULL);
16 }
17 //int t;
18 int main(int argc, char const *argv[])
19 {
20         pthread_t threads[NUM_THREADS];
21         int rc; 
22         int t;
23             
24         for (t = 0; t < NUM_THREADS; ++t)
25         {   
26                 printf("Creating thread %d\n",t);
27                 rc=pthread_create(&threads[t],NULL,(void *)PrintHello, (void *)&t);
28                 if(rc!=0){
29                         printf("error. return code is %d\n", rc);
30                         exit(-1);
31                 }   
32         //      sleep(1);
33 //              pthread_join(threads[t],NULL);
34         }   
35         pthread_exit(NULL);
36 }

在這里主線程創建8個子線程,8個子線程都運行同一個函數PrintHello,休眠1s后打印傳入的參數為t

運行結果如下,主線程打印完8條"Creating thread"后經過1s左右子線程打印8條"Hello from thread"

如果取消掉32行或33行的注釋,則出現正確的結果:

那為什么會這樣呢?先貼一張圖

這是函數調用過程圖。沒錯,在對於整個進程來說,主線程生成子線程在由子線程執行某個函數,對CPU來說就是函數調用。從第一次的運行結果可以看出,其執行順序應該是先主線程執行到pthread_exit()然后等待所有的子線程運行,那這樣,有8次參數傳遞,而且都是存放在同一個地址,即調用者棧幀的ebp+8這個位置,而這個存放的是主線程即main函數棧幀中t的位置。所以,經過一次又一次的覆蓋,主線程執行完后最終傳遞給子線程的應該是最后一次變動后的t。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM