2011-07-23 7 views
11

「tick tock」パターンで進行するには2つのスレッドが必要です。セマフォとimplmented場合、これは正常に見える:セマフォとしてミューテックスを使用しますか?

Semaphore tick_sem(1); 
Semaphore tock_sem(0); 

void ticker(void) 
{ 
    while(true) 
    { 
     P(tick_sem); 
     do_tick(); 
     V(tock_sem); 
    } 
} 

void tocker(void) 
{ 
    while(true) 
    { 
     P(tock_sem); 
     do_tock(); 
     V(tick_sem); 
    } 
} 

私は(技術的にはバイナリセマフォです)ミューテックスと同じことを行う場合は、それは奇妙なコードのにおいを持っています。

std::mutex tick_mutex; 
std::mutex tock_mutex; 
tock_mutex.lock(); 

void ticker(void) 
{ 
    while(true) 
    { 
     tick_mutex.lock(); 
     do_tick(); 
     tock_mutex.unlock(); 
    } 
} 

void tocker(void) 
{ 
    while(true) 
    { 
     tock_mutex.lock() 
     do_tock(); 
     tick_mutex.unlock(); 
    } 
} 

ミューテックスは別のスレッドに情報を伝えることを意図していないと思います。 (C++ 11の標準委員会は、予期せぬ情報転送を打ち負かすためにtry_lockに偽の失敗を追加しました;§30.4.1/ 14)mutexは変数へのアクセスを同期させ、別のスレッドに情報を伝えることができるようです。

最後に、std::condition_variableで実装されている場合は正しく見えますが、より複雑です(tick_vs_tock変数、mutex、および条件変数)。簡潔にするために実装を省略しましたが、実際はまっすぐです。

ミューテックス溶液は良好ですか?それとも何か微妙に間違っていますか?

考えていないマイティック/トックの問題を解決する良いパターンがありますか?

+0

BTW:この問題は、C++ 0xに 'std :: semaphore'がなく、二重' std :: mutex'ソリューションが 'std :: condition_variable'ソリューションより複雑ではないために発生します。 –

+3

(なぜ)それを保持していないスレッドのmutexを 'unlock()'することは有効ですか? –

+0

@Steveは本当に良い質問です(ヒント、ヒント、ナッジ、ナッジ)。 –

答えて

10

Mutexは単なるバイナリセマフォではなく、ロックスレッドだけがロックを解除できるという制限もあります。

あなたはそのルールを破っています。

編集:

MSDNから:

呼び出し元のスレッドが ミューテックスオブジェクトを所有していない場合ReleaseMutex機能に障害が発生しました。

を場合pthread_mutex_unlockの()関数は失敗することがあります:現在のスレッドがミューテックスを所有していない

EPERM Googleがpthread_mutex_unlockのために上がっていることをいくつかのサイトから

他のmutex実装でも同じことが分かります。 mutexはリソースへのスレッドのアクセスを守るため、別のスレッドはロックを解除できないはずです。

+0

Steveのコメントごとに。それは本当にルールですか?それは間違いなく良い考えです。 –

+0

@deft - システム依存のmutexの実装に依存していると思います。システムによって許可されていても、他人のミューテックスをロック解除することは、一般的には良い考えではありません。 – littleadv

+0

@deft_code:私はまだFDISのミューテックスセクションを読んでいませんが、もしそれが*ルールでなければ私は驚くでしょう。ミューテックスには所有者がいますが、それは同期ツールとしての基本的な定義の一部です。 –

9

セマフォを使用するケースがあるので、修正は移植可能だと思います。implement one using a mutex and a condition variable

セマフォごとにmutex/condvarペアを使用するため、これは特に効率的ではないかもしれませんが、独自のセマフォ(PosixやWindowsなど)を持つシステムでは別の実装に切り替えることができます。

明らかにsemaphores are "too error-prone"です。 Boostを尊重して、少なくとも私たちの一部は管理できると思います。確かにあなたは結び目trying to do complicated things with multiple semaphoresに身を置くことができ、かなり低レベルのツールです。しかし、彼らが正しいことだと問題はありません。

+0

私は、 "あまりにもエラーが発生しやすい"ことが奇妙であることに同意します。ミューテックスはエラーを起こしやすい。だからハンマーができます。 – asveikau

関連する問題