2016-04-15 13 views
-3

グローバルに2つのスレッドが同時に実行されるようにしようとしています。 コンパイラは、コンパイルの前に行を削除し、そのようwhileループでIf-elseステートメントが機能しません

char dir='w'; //global var 


UINT EditDir (LPVOID pParam);//accepts dir from user in a loop 
UINT Move (LPVOID pParam); //processes dir (its incomplete) 

int main() 
{ 
    ........ 
    ........ 
    CWinThread* pThread1 = AfxBeginThread(EditDir,(LPVOID)NULL); 
    CWinThread* pThread2 = AfxBeginThread(Move,(LPVOID)NULL); 
    WaitForSingleObject(pThread1, INFINITE); 
    ........ 
    ........ 
} 

UINT EditDir(LPVOID pParam) 
{ 
    bool end=false; 
    while (!end) 
    { 
     ::dir = getchar(); 
     Sleep(10); 
     if (::dir=='q')end=true;//*************************************** 
    } 
return 0; 
} 

UINT Move (LPVOID pParam) 
{ 
    //process dir in a loop 
    return 0; 
} 

if文は動作しません。

私がqを押した後、ループは終了するはずですが、それは継続します。

どこが間違っていますか?

+0

@EdHeal理由と理由を説明してください... –

+0

コンパイラの最適化が実際に理由であるかどうかを確認するために "-O0"フラグを付けてコンパイルしてみてください –

+0

スレッド間で通信がどのように行われているか、 。 –

答えて

0

最後に、私は間違いを発見した........

CWinThread* pThread2 = AfxBeginThread(Move,(LPVOID)NULL);// #1 
WaitForSingleObject(pThread1, INFINITE); //     #2 

pThread

は、クラスのオブジェクト.......ないハンドルと

WaitForSingleObject(HANDLE hHandle,DWORD dwMilliSeconds)// needs a handle 

です私たちはライン#1と#2の間に何をすべきかはのWaitForSingleObject(...)とないのpthreadで

HANDLE hThread; 
hThread=pThread->m_hThread; 

と合格hThreadです。

-1

多くのことがそのコードで間違っている可能性があります。

  • コンパイラは、dirがレジスタに格納され、他の関数に反映されないように最適化することがあります。
  • コンパイラまたはプロセッサが文を並べ替えると、何らかの異常な動作が発生する可能性があります。
  • エイリアシングを書き出します(あなたのコードは、dirの隣にある別の変数に書き込みます。プロセッサは、ブロックを使って書き込みを最適化し、効果的にdirを上書きします)。
  • 細い空気の結果が出ません。
  • 異なる値を保持するローレベル(L1)キャッシュに当たる。

などです。

スレッドセーフな構造を使用する必要があります。書き込みのエイリアシングやスレッドセーフではない他のコンパイラの最適化を防ぐためには、少なくともstd :: atomicを使用してください。 mutexを追加して、変数へのアクセスを保護することもできます。

おそらく、最良の設定は、あるスレッドが入力から文字を読み取り、よくテストされ、よくメンテナンスされたライブラリから得たプロデューサ - コンシューマキューまたは通信チャネルにコピーをプッシュする場合です。

+0

手元の質問とは関係ありません。 – SergeyA

関連する問題