2016-05-05 4 views
2

私は同じリソースを複数のスレッドでアクセスするマルチスレッドアプリケーションでstd::mutexを使用します。これは正常に動作します。しかし、私のコードのある時点では、TerminateThread(...)を使ってスレッドを終了させなければなりません。私は(_beginthreadexを使用して)再びスレッドを開始すると、それが終了したときのスレッドの一つが、ミューテックスロックにあった場合、私は例外を取得:C++マルチスレッドミューテックスロック "リセット"

同時実行:: improper_lock BEI Speicherort 0x03B4F3D0。

これはrtlocks.cppにスローされる、(bool critical_section::_Acquire_lockで)行1184:

LockQueueNode * pPrevious = reinterpret_cast<LockQueueNode *>(InterlockedExchangePointer(&_M_pTail, pNewNode)); 

私はmutexを "リセット" することができれば、私は右、例外になるだろう、と思いますか?これどうやってするの?

(私は<process.h>を使用)

編集

私は次のことを試してみました:

std::mutex dataStorage_lock; 
mutexHandler[0] = &dataStorage_lock; //storing all mutexs in an array 

//when trying to delete: 
delete mutexHandler[0]; 

をしかし、私は得る:

デバッグアサートに失敗しました!

式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)

+7

リファクタリング、コードをスレッドを終了する必要はありません。議論すべきことはもうありません。 –

+2

これは 'TerminateThread()'が安全でない理由の1つです。 https://blogs.msdn.microsoft.com/oldnewthing/20150814-00/?p=91811その記事には、Larry Ostermanのボーナス詩があります。「TerminateThreadを何度も電話しないでください」 –

答えて

5

、あなたのアイデアを取得するべきである::中断のいくつかのアイデアについては、こちらをご覧ください

間違っ:

function thread_proc(): 
    for_ever: 
    do_things 

function stop_my_thread(): 
    TerminateThread(...) 

右:

function thread_proc(): 
    while(not terminate_signal): 
    do_things 

function stop_my_thread(): 
    terminate_signal.set(); // signals the thread to terminate 
    thread.join();   // waits for the thread to terminate 
+0

シグナルとして、私は通常のブール値を使うことができます。 'bool doExit'です。スレッドを終了させたいときは、(私のメイン関数で) 'doExit = true'を設定します。しかし、スレッド内のif条件で取得されている間にtrueに設定するとエラーが発生する可能性があるので、別の 'mutex'を' doExit'にする必要があります。 – black

+1

あなたがアトミック(参照 'のstd :: atomic')またはcondition_variable('のstd :: condition_variable')のいずれかを使用する必要があります@black。 Windowsの世界では、非標準であると気にしないならば、 'Event'を使うことができます。通常の変数を使用するだけではありません。 C++標準では、あるスレッドで行われた変更が別のスレッドで発生するという保証はありません(これには、スレッド変数ではなく、I/O用です)。 –

+0

ありがとう! 'std :: atomic'はうまく動作します。 – black

2

あなたがミューテックスを破壊し、新しいものを作成する必要があるか、あなたはミューテックスで待機しているとき、スレッドがすることができるようにコードを変更することができます中断された(中止されるよりむしろ)。これは擬似コードであるhttp://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.interruption

+0

Iブーストを使わないでください。私はprocess.hをインクルードします。同様のソリューションですか? – black

+0

あなたの最初の解決策(ミューテックスを破壊する): 'myMutex = NULL'のようなものがありますか? – black

+0

@black:もしあなたが 'mutex * m = new mutex();'を持っていれば、後で 'delete m'を行い、最初から再び作成することができます。 –

関連する問題