none
スレッドプログラミングについて(VC++) RRS feed

  • 質問

  • 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;
    }
    2015年3月24日 7:28

回答

  • アクセスエラーはどの行で発生したのでしょうか? 当該行に問題があると思われます。
    • 回答としてマーク 星 睦美 2015年4月2日 6:13
    2015年3月24日 8:26
  • answers フォーラムの方に添付された画面を見る限り、例外コード 0xc0000005 (EXCEPTION_ACCESS_VIOLATION) でアプリが落ちている様なので、デバッガ上で動かして、アクセス違反例外発生時のコール スタックを張り付けた方が早いのでは?
    それか、アプリ クラッシュ時のプロセス ダンプを採取して、解析できる人に見てもらうとか。
    • 回答としてマーク 星 睦美 2015年4月2日 6:12
    2015年3月24日 9:53
  • >また、スレッドを使用しない場合、ご指摘いただいたコードで試してみましたが、同じエラーが発生するといった状況です。

    そうなると、スレッドを利用していること自体はエラーの原因ではないということです。
    エラーが 0xC0000005 (一般保護例外)であるなら、FileSaveThread()関数に渡った
    FILESAVEデータに問題がある可能性が高いです。
    お馬鹿さまの提案通り、デバッグ実行してみるのが一本道だと考えられます。
    このときスレッドを使う必要はありません。Cam3データの時、FileSaveThread()関数の
    開始付近でブレークして、同エラーが発生するまで地道にステップ実行してみてはどうでしょう。


    2015年3月25日 5:32

すべての返信

  • アクセスエラーはどの行で発生したのでしょうか? 当該行に問題があると思われます。
    • 回答としてマーク 星 睦美 2015年4月2日 6:13
    2015年3月24日 8:26
  • 自分も質問があります。

    const int CAM_NUM = 4;
    FILESAVE   filesave[ CAM_NUM];  // [0]:Cam1 [1]:Cam2 [2]:Cam3  [3]:Cam4

    という状態でしょうか。
    もう一丁。スレッドを使用しない場合・・・つまり

     for(i = 0;i < CAM_NUM;i++) {
        FileSaveThread( (LPVOID)( &filesave[i])));
     }

    の時にも同じエラーが出ますか?

    2015年3月24日 9:15
  • answers フォーラムの方に添付された画面を見る限り、例外コード 0xc0000005 (EXCEPTION_ACCESS_VIOLATION) でアプリが落ちている様なので、デバッガ上で動かして、アクセス違反例外発生時のコール スタックを張り付けた方が早いのでは?
    それか、アプリ クラッシュ時のプロセス ダンプを採取して、解析できる人に見てもらうとか。
    • 回答としてマーク 星 睦美 2015年4月2日 6:12
    2015年3月24日 9:53
  • コメントありがとうございます。

    該当行を確認してみます。

    2015年3月25日 4:57
  • コメントありがとうございます。

    CAM_NUMはヘッダファイルのほうで、#defineで定義しているので書き換えは可能です。

    また、スレッドを使用しない場合、ご指摘いただいたコードで試してみましたが、同じエラーが発生するといった状況です。

    2015年3月25日 5:01
  • コメントありがとうございます。

    大変恐縮なのですが、プログラミング初心者なものでして、コールスタックやプロセスダンプという用語を初めて耳にしました。

    問題解決に向け参考にさせていただきます。

    2015年3月25日 5:06
  • >また、スレッドを使用しない場合、ご指摘いただいたコードで試してみましたが、同じエラーが発生するといった状況です。

    そうなると、スレッドを利用していること自体はエラーの原因ではないということです。
    エラーが 0xC0000005 (一般保護例外)であるなら、FileSaveThread()関数に渡った
    FILESAVEデータに問題がある可能性が高いです。
    お馬鹿さまの提案通り、デバッグ実行してみるのが一本道だと考えられます。
    このときスレッドを使う必要はありません。Cam3データの時、FileSaveThread()関数の
    開始付近でブレークして、同エラーが発生するまで地道にステップ実行してみてはどうでしょう。


    2015年3月25日 5:32
  • イカロンゲ さん、こんにちは。
    フォーラム オペレーターの星 睦美です。

    フォーラム ユーザーからの回答が参考になったとのことで、今回は私のほうで[回答としてマーク] して回答を終了させていただきますね。
    今後もプログラミングに関しての質問がありましたらMSDN フォーラムに投稿いただければと思います。

    ではこれからもよろしくお願いします。


    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2015年4月2日 6:21