トップ回答者
スレッドプログラミングについて(VC++)

質問
-
Visual Studio 2010 Professional SP1で開発を進めており、スレッドプログラミングについて質問したいことがございます。
[質問内容]
カメラ4台の画像データをユーザーバッファに集録(1500枚/カメラ1台)し 、集録が終わった後にファイルスレッドを起動しそれぞれの保存場所
(Cam1とCam2はローカルディスク(E) , Cam3とCam4はボリューム(G))に同時にファイル書き込みを行っているのでが、書き込み速度にばらつきがあり
Cam3とCam4のファイル生成が終了した時点でアクセスエラーが発生します。
処理の流れとしては、AfxBeginThreadをカメラの台数分呼び出し、ファイル保存スレッド内でファイル書き込み処理を行っております。
スレッド間の同期が取れていないためこのようなエラーが発生したと推測するのですが、分かる方がいましたら、ご教授のほどよろしくお願いいたします。
// ファイル保存スレッド
for(i = 0;i < CAM_NUM;i++) {
AfxBeginThread(FileSaveThread , (LPVOID)&filesave[i]);
}
/************************************************************
ファイル保存スレッド
************************************************************/
static UINT FileSaveThread(LPVOID pParam)
{
FILESAVE *FileSave_str = (FILESAVE*)pParam;
CImage myImage;
int i , j;
int s_Pos , c_Pos;
unsigned char *pixcel; // 先頭アドレス取得用
unsigned char *pixcelPos; // アドレス操作用
unsigned char *userBufPos; // アドレス操作用
// ダミーの静止画読み込みmyImage生成
myImage.Load( _T("DUMMYIMAGE.bmp" ) );
// 行の先頭と次の行の先頭までのメモリアドレス間のサイズ(バイト) 3*1296 戻り値が正 -> 原点は左上隅 , 戻り値が負 -> 原点は左下隅
FileSave_str->pitch = myImage.GetPitch(); // ビットマップ行の先頭およびビットマップ次の行の先頭間でのアドレス間の距離
FileSave_str->pixcel = (unsigned char*)myImage.GetBits(); // ダミーの静止画の先頭アドレス取得
pixcelPos = FileSave_str->pixcel; // アドレス操作用
s_Pos = imgpos[FileSave_str->cameraNum].s_Pos;
c_Pos = imgpos[FileSave_str->cameraNum].c_Pos;
for(i = 0; i < FileSave_str->saveNum; i++) {
userBufPos = imgdata[FileSave_str->cameraNum][s_Pos].userBuf + (DCF_SIZE_X * 3 * (DCF_SIZE_Y - 1));
for( j = 0; j < DCF_SIZE_Y; j++ ) {
pixcelPos = pixcelPos + (j * FileSave_str->pitch);
memcpy(pixcelPos , userBufPos , DCF_SIZE_X * sizeof(unsigned char) * 3); // 1行ずつコピー
userBufPos = userBufPos - (DCF_SIZE_X * 3); // 参照(ユーザー定義)バッファを次の行へ移す
pixcelPos = FileSave_str->pixcel;
}
// s_Posの状態確認
s_Pos++;
if(s_Pos > N) {
s_Pos = 0;
}
if(j % 2 == 0) {
Sleep(200);
}
myImage.Save((CString)FileSave_str->fileName[i]);
}
return 0;
}
回答
-
>また、スレッドを使用しない場合、ご指摘いただいたコードで試してみましたが、同じエラーが発生するといった状況です。
そうなると、スレッドを利用していること自体はエラーの原因ではないということです。
エラーが 0xC0000005 (一般保護例外)であるなら、FileSaveThread()関数に渡った
FILESAVEデータに問題がある可能性が高いです。
お馬鹿さまの提案通り、デバッグ実行してみるのが一本道だと考えられます。
このときスレッドを使う必要はありません。Cam3データの時、FileSaveThread()関数の
開始付近でブレークして、同エラーが発生するまで地道にステップ実行してみてはどうでしょう。
すべての返信
-
>また、スレッドを使用しない場合、ご指摘いただいたコードで試してみましたが、同じエラーが発生するといった状況です。
そうなると、スレッドを利用していること自体はエラーの原因ではないということです。
エラーが 0xC0000005 (一般保護例外)であるなら、FileSaveThread()関数に渡った
FILESAVEデータに問題がある可能性が高いです。
お馬鹿さまの提案通り、デバッグ実行してみるのが一本道だと考えられます。
このときスレッドを使う必要はありません。Cam3データの時、FileSaveThread()関数の
開始付近でブレークして、同エラーが発生するまで地道にステップ実行してみてはどうでしょう。