C++用pthread_create()創建線程


pthread_create()是Linux中創建線程的一種方式。

#include<pthread.h>
 
int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*) ,void *arg);
 
//第一個參數為指向線程標識符的指針。
//第二個參數用來設置線程屬性。
//第三個參數是線程運行函數的起始地址。
//第四個參數是運行函數的參數。
//pthread_create() 在調用成功完成之后返回零。其他任何返回值都表示出現了錯誤。

用到多線程,就用for語句循環創建多個線程,但是出現了一些問題,特此記錄下。

原代碼:

pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
    pthread_create(&pt[a],NULL,function,&a);
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

創建線程時是需要把a傳入函數function中的,但是,這樣會出現混亂,比如,我們需要往第0個線程傳入參數0,實際上運行結果顯示傳入第0個線程的參數不是0。

網上查詢資料之后,大概問題就是,CPU運行速度很快,而pthread_create()創建線程要有一定的時間,在pthread_create()創建線程再去按照之前參數a的地址去取a時,循環中a的值已經發生了變化,這就造成傳入函數function的參數值不對。

既然這樣,就讓主線程循環時等一下pthread_create(),於是代碼變成下面這樣:

pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
{
    pthread_create(&pt[a],NULL,function,&a);
    sleep(1);  //#include<unistd.h>
}

for(int a=0;a<num_threads;a++) {
  pthread_join(pt[a],NULL);
}

循環時主線程掛起1秒鍾,pthread_create()就創建線程完畢了,但這樣帶來的問題就是:我們使用多線程的初衷就是並行運算、提升效率,但每創建一個線程就能停1秒,如果我們創建線程的次數比較多,那將大大影響程序的整體運行效率。試了一下,如果將sleep(1)改成usleep(1000),即睡眠1000微秒(1毫秒),仍可能出現錯誤。

通過網上資料,經過實踐,發現以下兩種方法可以解決:

  1、實現開辟一塊空間存儲創建多線程時所需要傳入的參數,這樣每個線程的參數的地址就不會亂套。

  2、在循環創建線程時,我們不直接把循環的控制變量(如上例中的a)直接傳入多線程的函數中,我們另外申請一塊空間,存儲在這塊空間上,到時再從這塊空間取值就行了。

種方法的解決方法如下:

//第一種方法
 
pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
int order[num_threads];
for(int a=0;a<num_threads;a++)
    order[a]=a;
for(int a=0;a<num_threads;a++)
    pthread_create(&pt[a],NULL,function,&order[a]);
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);
 
 
//第二種方法
pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
{
    int* temp=(int*)malloc(sizeof(int));
    *temp=a;
    pthread_create(&pt[a],NULL,function,(void*)temp);
}
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

兩種效果方法差不多,但是第二種方法使用malloc申請了動態內存,而且還沒有釋放,所以不是太好。


免責聲明!

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



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