2014-10-27 99 views
0

我想使用多線程來允許兩個任務在一個DLL內並行運行,但我的應用程序不斷崩潰,顯然是由於一些不良的資源衝突管理;這裏是詳細信息: 我需要沿着主邏輯流從某個點調用相同的函數(DoGATrainAndRun),爲其中一個參數傳遞不同的值,讓這兩個參數運行,然後返回到主邏輯流程,並使用2次調用返回的兩組(不同)值。c多線程衝突

(這是在主頭文件):

typedef struct 
{ 
    int PredictorId; 
    int OutputType; 
    int Delta; 
    int Scale; 
    int Debug; 
    FILE* LogFile; 
    int TotalBars; 
    double CBaseVal; 
    double* HVal; 
    int PredictionLen; 
    double*** Forecast; 
} t; 

(這是在主邏輯流):

hRunMutex=CreateMutex(NULL, FALSE, NULL); 
arg->OutputType=FH; 
handle= (HANDLE) _beginthread(DoGATrainAndRun, 32768, (void*) arg); 

arg->OutputType=FL; 
handle= (HANDLE) _beginthread(DoGATrainAndRun, 32768, (void*) arg); 

do {} while (hRunMutex!=0); 

CloseHandle(hRunMutex); 

(這是在DoGaTrainAndRun的結尾):

free(args); 
ReleaseMutex(hRunMutex); 

我很新的多線程,我似乎無法弄清楚這一個...

+1

看起來您正在傳遞相同的'arg'兩個線程。這可能是錯誤的。 – dohashi 2014-10-27 15:04:31

+0

你爲什麼這麼說?正如你所看到的,我在調用_beginthread之前設置了arg-> OutputType – gcaglion 2014-10-27 15:07:02

+0

您可以將整個線程proc代碼與抓取/釋放互斥鎖的地方一起發佈嗎? – Lundin 2014-10-27 15:10:49

回答

0

有幾件事情:

首先,你傳遞相同結構轉換爲兩個線程,但僅更改OutputType值。如果可能的話,第一個線程將會看到FL並且從不會看到值FH。原因是線程是如何安排的。這對你的第一個線程開始並暫停有效。然後,您的主線程創建第二個線程,將OutputType設置爲FL。這個線程開始並且第一個也恢復。但是,第一個現在看到OutputTypeFL

接下來,兩個線程都使用相同的結構,但其中一個線程正在釋放內存。如果另一個線程在其他版本之後仍然在使用它,那麼在仍然使用它的線程中會出現未定義的行爲。這可能會導致崩潰。

您試圖等待線程退出是錯誤的。你不需要互斥體,你當然不需要旋轉它來測試零。只需使用WaitForMultipleObjects

HANDLE handles[2]; 

handles[0] = (HANDLE)_beginthread(...); 
handles[1] = (HANDLE)_beginthread(...); 

WaitForMultipleObjects(2, handles, TRUE, INFINITE); 

這將從轉圈浪費CPU週期,停止你的主線程。當等待返回時,你會知道兩個線程都已完成。

把所有這些組合起來應該給你這樣的事情:

HANDLE handles[2]; 

t *arg1=malloc(sizeof(t)); 
arg1->OutputType=FH  
handles[0] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg1); 

t *arg2=malloc(sizeof(t)); 
arg2->OutputType=FL  
handles[1] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg2); 

WaitForMultipleObjects(2, handles, TRUE, INFINITE); 
free(arg1); 
free(arg2) 

不要在DoGATrainAndRun釋放任何內存。

+0

感謝您的詳細輸入;然而,我仍然必須錯過一些東西,因爲行爲沒有改變;我現在擁有以下內容:\t'HANDLE handle [2]; \t int ThreadId; \t t * arg [2]; ' – gcaglion 2014-10-27 16:04:10

+0

'hRunMutex = CreateMutex(NULL,FALSE,NULL); \t \t \t \t \t爲(I = 0; I PredictorId = pr_id; ARG [I] - >德爾塔= VDELTA; ARG [Ⅰ] - >比例= vHpScale; ARG [I] - >調試= pDebug; ARG [I] - >日誌文件= pLogFile; ARG [I] - > TotalBars = pTotalBars; ARG [I] - > CBaseVal = CBaseVal; ARG [I] - > HVal = vHVal [vPredictorType]; ARG [I] - > PredictionLen = pPredictionLen; ARG [Ⅰ] - >預測= oForecast; \t \t \t \t \t \t arg [i] - > OutputType = i; handle [i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DoGATrainAndRun,(void *)arg [i],0,&ThreadId); \t \t \t \t \t}' – gcaglion 2014-10-27 16:05:01

+0

'WaitForMultipleObjects(MAX_THREADS,handle,TRUE,INFINITE); \t \t \t \t \t爲(i = 0; I gcaglion 2014-10-27 16:05:59