1. 程式人生 > >C++用pthread_create()建立執行緒時需要注意的問題

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()不就ok了,於是程式碼變成下面這樣:

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申請了動態記憶體,而且還沒有釋放,所以不是太好。

我疑惑的是,在一些地方,如下的程式碼竟然能跑,而且完全沒問題。。。?(感覺和我寫的一模一樣啊= - =)我也沒搞懂沒什麼,真的很奇怪。歡迎懂得大佬們留言我。

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);

參考:

相關推薦

C++pthread_create()建立執行需要注意的問題

pthread_create()是Linux中建立執行緒的一種方式。 #include<pthread.h> int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*star

學習筆記:windows下,c語言來建立執行

#include <stdio.h>#include <windows.h> typedef void * HANDLE;#define SEMAPHORE HANDLE#define THREADHANDLE HANDLE#define THREAD

VC CreateThread(),建立執行為什麼執行函式一定需要static修飾

因為,當把執行緒函式封裝在類中,this指標會作為預設的引數被傳進函式中,從而和執行緒函式引數(LPVOID lpParameter)不能匹配,不能通過編譯。此時,就需要把執行緒函式在定義的時候,最前面加上static。 當執行緒函式不在類裡面時,就不會出現此類問題。

Python多工(利用threading建立執行傳入引數--args引數)

  target  : 指定 這個執行緒去哪個函式裡面去執行程式碼   args:     指定將來呼叫 函式的時候   傳遞什麼資料過去         &n

關於在C++類裡面建立執行

將執行緒函式宣告為靜態函式或者友元函式,但是靜態函式只能訪問靜態成員變數,所以利用引數將this傳進函式來,就可以通過該指標訪問類成員變數和函數了。具體例子: 不多說了,直接上程式碼: lll.h #include<afxwin.h> #include<

ThreadPoolExecutor建立執行池的優點

現在做開發的童鞋,越來越多的人在建立執行緒池用ThreadPoolExecutor,而不是用JDK提供的四種方法來建立 一、執行緒池的背景: 1、執行緒是稀缺資源,使用執行緒池可以減少建立和銷燬執行緒的次數,每個工作執行緒都可以重複使用。 2、可以根據系統的承受能力,調整執行緒池中工作執

【Linux開發技術之常見問題】一個建立執行常見的問題:invalid conversion from `void*' to `void*(*)(void*)

void main_thread ( void *ptr ) {   char *message1 = "Thread 1";   char *message2 = "Thread 2";   pthread_t thread3, thread4;   int iret3, iret4;  

pthread_create()建立執行最大個數

執行緒應用程式最常見導致建立執行緒失敗的原因是執行緒棧大小的設定。建立一個新的執行緒,預設情況下系統為執行緒棧預留了2MB的定址空間。執行緒棧起始於程序虛擬 記憶體的高階地址,並向虛擬記憶體底端地址方向擴充套件。取決於執行緒本身的大小以及其它執行緒記憶體分配的情況,程序虛

執行pthread_create建立執行

pthreads定義了一套C程式語言型別、函式、與常量。以pthread.h和一個執行緒庫實現。 資料型別: pthread_t:執行緒控制代碼 pthread_attr_t:執行緒屬性 執行緒操作函式: pthread_create():建立一個執行緒 pthread_e

基於Linux c socket和執行 實現的簡易聊天室之伺服器

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #

JavaScript執行問題需要注意的情況:

1、避免編寫計算密集的前端程式碼。 2、使用非同步Ajax。 3、避免編寫一個需要較長時間來執行的JS程式碼,比如生成一個大型的表。遇到這種情況,可以分批執行,比如用setInterval來每秒生成20行,或是使用者向下拖動滾動條時候再繼續產生新的行。 4、在頁

Qt中使用執行注意事項(執行沒起作用的原因)

今天偶然發現,執行程式時程式輸出視窗中有如下提示:  QObject::startTimer: Timers can only be used with threads started with QThread 也就是當物件有父物件時,是不可以移到其他執行緒當中去的。 程式

建立執行,為何建立需要Sleep?

後面的執行緒用到了前面執行緒初始的結構,sleep一下只是做到了使前一個執行緒初始化完成後後一個執行緒才開始執行。但這樣不嚴格,需要同步機制。在麼多個執行緒都要用的資料結構不要放到子執行緒內部去初始化,程式啟動時全部初始化好。

使用pthread_create建立大量執行建立執行失敗,Resource temporarily unavailable的解決辦法

        今天在一個測試程式中使用pthread_create建立了大量執行緒,但是如果執行緒數量增加到400後,就會出現執行緒建立失敗,perror打印出的錯誤原因是:Resource temporarily unavailable。        在網上查了下,原

C#:執行(2):建立執行

一:建立新執行緒 在C#裡,執行緒是一種已經定義好的類,其被定義在System.Threading名稱空間內,因此建立新執行緒和我們例項化物件並沒有本質的差別。在這裡,用一個最簡單的例子說明如何建立新執行緒。 (一):建立新的控制檯程式,在控制檯程式的主函式下面,寫一個希望在新執行緒中呼叫的

C++ 建立執行的方法

c++開發過程中,建立執行緒是必不可少的,今天就給大家說說c++建立執行緒的方法,主要介紹我常用的2種方法。 第一種:CreateThread HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttribute

C++ STL 建立執行的三種方式

使用 stl thread 編寫多執行緒程式時,編譯需要加 -pthread 通過函式指標建立執行緒 #include <iostream> #include <thread> using namespace std; void func(int id

c#建立執行監聽網路埠

背景 需要寫一個TcpClient的資料監聽。為了實現不間斷監聽,需要寫一個無限迴圈的執行緒。 using System.Threading; 程式碼實現 private void ZQWLconnect() { //新建執行

建立執行:CreateThread與pthread_create引數比較

建立執行緒 在 Windows 中,您可以使用 CreateThread() 來建立執行緒,建立的執行緒在呼叫程序的虛擬地址空間中執行。 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD SIZE_T d

《捕魚達人》去理解C#中的多執行

執行緒是程序中某個單一順序的控制流,是程式執行中的排程單位,是程式執行流的最小單位,一個標準的執行緒由執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。 執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。 執行緒也