2011-01-21 21 views
6

私は、並行性と競合状態に関する章「Linuxデバイスドライバ第3版」を読んでいます。私が完全に理解していない例があります。彼らは現在のスレッドの外で(例えば、新しいカーネルスレッドやユーザプロセス、既存のプロセスの要求、またはハードウェアベースのアクションのための)活動を開始する必要があるときに、カーネルプログラミングの共通パターンについて話しています。コンプリート。非常に効果的ではない解決策の例は次のとおりです。Linuxカーネルミューテックス

struct semaphore sem; 
init_MUTEX_LOCKED(&sem); 
start_external_task(&sem); 
down(&sem); 

その後、彼らはその作業が行われたときに外部タスクが(& SEM)を呼び出すことをお勧めします。

我々はこのようにそれを行うことができない理由を私は理解していない:

struct semaphore sem; 
down(&sem); 
start_external_task(&sem); 

ロック状態でミューテックスを作成し、タスクが開始された後に、ミューテックスを取得する必要があるのはなぜ?

あなたからのご意見をお待ちしております。ありがとう。

答えて

10

down()を呼び出すと、別のスレッドがセマフォを通知するまでスレッドがブロックされます。他のスレッドはまだ開始されていないため、スレッドは無期限にブロックされます。そのため、まずスレッドを開始し、スレッドが終了するまでブロックするためにdown()を呼び出す必要があります。

down()を呼び出す前にスレッドが終了すると、セマフォが通知され、down()がシグナルをクリアして戻るため、okです。

+6

+1ですが、私はmutexの代わりに 'semaphore'という言葉を使うのが良いと思います。 SEMAPHORE:どのスレッドでも上/下が可能です。 MUTEX:所有権を持ちます。ロック所有者スレッドのみがmutexを上げることができます。この場合、セマフォを使用する必要があります。スレッド間の通信が目的です。 – Vojta

+0

@Vojita:私は同意します。私はミューテックスという用語を使用しました。なぜなら、その質問はセマフォをミューテックスと呼んでいるからです。 –

3

最初の例では、down(& sem)は、external_taskが呼び出され(& sem)、タスク完了までメインスレッドを効果的に一時停止するのを待ちます。ダウンあなたのコードで ()は、タスクが(呼び出すことはまだありませんので、永遠にメインスレッドをロックします)

1

コール:

init_MUTEX_LOCKED(&sem); 

は0に初期化「ミューテックスモード」での新しいセマフォを作成します。つまり、down()への呼び出しがブロックされます。対応するコール:

init_MUTEX(&sem); 

はあなたが0にセマフォを初期化する最初の例では1

に初期化セマフォを作成し、あなたのexternal_taskを作成し、あなたのタスクはup()を呼び出すまでブロックdown()を呼び出します。

2番目の例では、セマフォを初期化せずにdown()ブロッキングの実行を呼び出し、external_taskを実行しないでください。up()を呼び出してブロックを解除できます。したがって、create external_taskへの呼び出しには決して達しません。

ちなみに、init_MUTEX_LOCKEDでセマフォを初期化するプロセスは、カーネル2.6.37カーネルでは削除されています。