2011-11-15 25 views
1

私は、特にWindowsのスレッドプログラムで少し錆びています。 Matlabで単純なmexファイルを作成しました。このファイルは、各ファイルが独自のスレッドで読み取られている状態で多数のファイルを読み込むためのものです。 ファイルは本当に便利ですが、このファイルに入れられているすべての機能を使用するより複雑なバージョンの前身です。C++ウィンドウのスレッディングとミューテックスの問題

#include <windows.h> 
#include "mex.h" 
#include <fstream> 

typedef unsigned char uchar; 
typedef unsigned int uint; 

using namespace std; 

int N; 
int nThreads; 
const int BLOCKSIZE = 1024; 
char * buffer; 
char * out; 
HANDLE hIOMutex; 

DWORD WINAPI runThread(LPVOID argPos) { 
    int pos = *(reinterpret_cast<int*>(argPos)); 

    DWORD dwWaitResult = WaitForSingleObject(hIOMutex, INFINITE); 

    if (dwWaitResult == WAIT_OBJECT_0){ 
     char buf[20]; 
     sprintf(buf, "test%i.dat", pos); 
     ifstream ifs(buf, ios::binary); 

     if (!ifs.fail()) { 
      mexPrintf("Running thread:%i\n", pos); 
      for (int i=0; i<N/BLOCKSIZE;i++) { 
       if (ifs.eof()){ 
        mexPrintf("File %s exited at i=%i\n", buf, (i-1)*BLOCKSIZE); 
        break; 
       } 
       ifs.read(&buffer[pos*BLOCKSIZE], BLOCKSIZE); 
      } 
     } 
     else { 
      mexPrintf("Could not open file %s\n", buf); 
     } 

     ifs.close(); 
     ReleaseMutex(hIOMutex); 
    } 
    else 
     mexPrintf("The Mutex failed in thread:%i \n", pos); 


    return TRUE; 
} 

// 0 - N is data size 
// 1 - nThreads is number of threads 
// 2 - this is the output array 

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { 
    N = mxGetScalar(prhs[0]); 
    nThreads = mxGetScalar(prhs[1]); 
    out = (char*)mxGetData(prhs[2]); 
    buffer = (char*)malloc(BLOCKSIZE*nThreads); 
    hIOMutex= CreateMutex(NULL, FALSE, NULL); 

    HANDLE *hArr = (HANDLE*)malloc(sizeof(HANDLE)*nThreads); 
    int *tInd = (int*)malloc(sizeof(int)*nThreads); 

    for (int i=0;i<nThreads;i++){ 
     tInd[i]=i; 
     hArr[i] = CreateThread(NULL, 0, runThread, &tInd[i], 0, NULL); 
     if (!hArr[i]) { 
      mexPrintf("Failed to start thread:%i\n", i); 
      break; 
     } 
    } 

    WaitForMultipleObjects(nThreads, hArr, TRUE, INFINITE); 

    for (int i=0;i<nThreads;i++) 
     CloseHandle(hArr[i]); 

    CloseHandle(hIOMutex); 
    mexEvalString("drawnow"); 
    mexPrintf("Finished all threads.\n"); 

    free(hArr); 
    free(tInd); 
    free(buffer); 

私はMatlabの中でこのようにそれをコンパイルします:このような

mex readFile.cpp 

し、それを実行します。ここで はコードです

out = zeros(1024*1024,1,'uint8'); 
readFile(1024*1024,nFiles,out); 

問題は、私がNFILESを設定するとき64以下であればすべて期待どおりに動作し、次の出力が得られます。

私は65以上にNFILESを設定するとき

は、しかし、私は得る:

Running thread:0 
Running thread:1 
Running thread:2 
Running thread:3 
The Mutex failed in thread:59 
The Mutex failed in thread:60 
The Mutex failed in thread:61 
. 
. 
. 
(up to nFiles-1) 
Finished all threads. 

私はスレッドなしでそれをもテストして、それが正常に動作します。

私は何が間違っているのか、ミューテックスを使用することのカットオフがとても恣意的であるのを見ることができないので、私が考慮していないことがあると仮定しています。 誰かが私が見ているエラーに関連して露骨な間違いを抱えているのを見ることができますか?

答えて

3

WaitForMultipleObjectsのドキュメントでは、「オブジェクトハンドルの最大数はMAXIMUM_WAIT_OBJECTSです。」(ほとんどのシステムでは64です)です。

これはまた、this threadの(ほぼ)重複しています。要約は実際にはそうです。制限は64です。また、WaitForMultipleObjectsの備考セクションの情報を使用して、待機するスレッドのツリーを構築することもできます。

+0

ありがとうございます!私はそれはそれのようなものだと思ったが、見る方法を確かめなかった。 – twerdster

+0

@twerdster - 私のやり方は、通常、機能していない関数、または何か関連する関数のリファレンスを見るだけです。この場合、 'WaitForSingleObject'が失敗している可能性があります。また、スレッドが強制終了されない限り、失敗する可能性はないので、' WaitForMultipleObjects'はおそらく失敗しています。表示される制限は、ドキュメントで制限やその他のものを検索するのにも役立ちます。 – slugonamission

関連する問題