迴圈建立多執行緒時保證引數的有效性 (轉)

worldblog發表於2007-12-11
迴圈建立多執行緒時保證引數的有效性 (轉)[@more@]

迴圈建立多執行緒時保證引數的有效性:namespace prefix = o ns = "urn:schemas--com::office" />

當我們需要在一個迴圈中傳遞引數時,使用使用的方法一般都是:

for(int I=0;I<100;I++){

  fun(I);  //使用函式傳遞i

}

每一個迴圈都會等待fun(I);函式完後再進行下一個迴圈。

但是當我們需要這個迴圈中建立執行緒,並將I的引數傳遞給執行緒時,如依然使用以上方法,會造成什麼情況呢?

D WIN ThreadFun(LPVOID lpParam){  //執行緒函式

  Int *I = (int *)lpParam;

  Return 0;

}

 

int I;

for(I=0;I<100;I++){

DWORD dwThreadId;

  HANDLE hThread;


 hThread = CreateThread(NULL,0,ThreadFunc,&I,0,&dwThreadId);


}

好了,到這裡我們就可以發現,在迴圈中,我們建立執行緒並傳遞的引數是I=1後,主有可能在執到下一次迴圈時,第一次的ThreadFun函式仍未執行,而此時的I已經等2了,如果ThreadFun再來  Int *I = (int *)lpParam;語句時,顯然不是我們想要的結果。

 

解決此問題的一種方法,便是可以使用靜態陣列來儲存所要傳遞的引數。如下:

int I;

static int nPara[100];   //此句需定義為全域性

for(I=0;I<100;I++){

DWORD dwThreadId;

HANDLE hThread;


NPara[I]=I;    //儲存引數


  hThread = CreateThread(NULL,0,ThreadFunc,&nPara[I],0,&dwThreadId);


}

此時,所有引數均儲存在nPara陣列中,剛才的問題是解決了。

接下來又有了新的問題,讓我們一起來看看吧:

1、如果需要建立的執行緒不止100,而是非常的大,而且我們也並不知道會有多少次迴圈的時侯。

2、如果我們需要傳遞的引數不單單只是一個int型的I,而是一個類。那麼我們宣告的時侯(假設執行緒數量最大為65535)則:

static CMYClass myClass[65535];

編譯之後,得到的將會堆上一大堆的垃圾。相信任何一位程式都不想看到自己的程式上面堆了一堆垃圾在上面吧。

那麼,還有沒有更好的辦法解決呢。答案是一定的,這裡,我就講一下我自己常用的方法:

動態建立對像傳遞引數。

一提到動態建立,我們自然會想到new 與 delete ,對了,我想說的也正是他們的使用。

假設引數型別為:

typedef struct _PARA{

  int I;

  DWORD dwNumber;

  HWND hOther;

}Para;

使用new 在堆疊中申請一遍空間,在使用完後必需使用delete將其釋放。

int I;

for(I=0;I<100;I++){

DWORD dwThreadId;

HANDLE hThread;


Para *myPara = new Para;


MyPara->I = I;


MyPara->dwNumber = 0 ;//自定


MyPara ->hOther = GetSafeHWnd();//當前窗體控制程式碼


  hThread = CreateThread(NULL,0,ThreadFunc,myPara,0,&dwThreadId);


}

 

//執行緒函式

DWORD WINAPI ThreadFun(LPVOID lpParam){  //執行緒函式

  Para *myPara = (Para *)lpParam;

  //執行其他功能

  delete [] myPara;    //釋放

  Return 0;

}

這樣的話,也就不怕傳遞的引數多少與執行緒的數量太大了。另外如有需要的話可以加上一個執行緒計數器,保證當前執行緒的最大數量。

通常情況,我比較喜歡把執行緒處理放在一個類中處理,在主程式中儘量不與執行緒打交道。

 

以上是我在寫ScanPort中遇到的一點點小問題,這裡拿出來給大家一起分享,如果您有更好的方法,也請拿出與我們一起論討。

 

AntGhazi/2001.12.21

to:antghazi@163">mailto:antghazi@163.net


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991288/,如需轉載,請註明出處,否則將追究法律責任。

相關文章