1.トピック
2.アイデア
リートコードでこの種のマルチスレッド問題を実行するのはこれが初めてです。この種の「同期」問題では、スレッドをブロックする必要がある場所(PV操作のPに対応)を理解してから、対応するVパート(リリースリソース)。また、ここでのトピックでは、重要なリソースへのアクセス(相互排除関係)を調べる必要はなく、同期関係のみを考慮する必要があります。まず、printBはAが印刷を完了するのを待つ必要があるため、ブロックする必要があります。そのため、ここではPa操作が必要です(下図を参照)。V部分はリソースが解放される場所です。 Aが印刷された後、Vaを印刷する必要があります。つまり、Bをウェイクアップして印刷を開始します。BとCの関係は同じです。
a
同期セマフォ:Bが取得するAの印刷リソースと理解でき、初期値は0です。
b
同期セマフォ:同様に、初期値は0です。
C ++標準ライブラリにはセマフォの実装とカプセル化はなく、C言語を使用できます<sempahore.h>
。
(1)sem_init
関数:関数を呼び出すために必要なヘッダーファイル:semaphore.h
- 関数プロトタイプ:
int sem_init(sem_t *sem, int pshared, unsigned int value);
- パラメータの説明:
- sem:セマフォオブジェクトを指します
- pshared:セマフォのタイプを示します。1の場合はプロセスに使用され、0の場合はスレッドに使用されます。
- value:セマフォ値のサイズを指定します
- 戻り値:成功すると0が返され、失敗すると-1が返され、errnoが設定されます。
- 役割:セマフォを作成し、セマフォ値に初期値を割り当てます。
(2)sem_post
関数:関数を呼び出すために必要なヘッダーファイル:semaphore.h
- 関数プロトタイプ:
int sem_post(sem_t *sem);
- パラメータの説明:
- sem:セマフォオブジェクトを指します
- 戻り値:成功すると0が返され、失敗すると-1が返され、errnoが設定されます。
- 機能:不可分操作でセマフォを1つ増やします
(3)sem_wait
:関数を呼び出すために必要なヘッダーファイル:semaphore.h
- 関数プロトタイプ:sem_wait(sem_t * sem);
- パラメータの説明:
- sem:セマフォオブジェクトを指します
- 戻り値:成功した場合は0を返し、失敗した場合は-1を返し、errnoを設定します
- 関数:セマフォをブロックして待機します。セマフォの値がゼロより大きい場合は、関数を実行してセマフォを1つ減らします。セマフォがゼロの場合、関数を呼び出すスレッドはブロックします。
3.コード
#include <semaphore.h>
class Foo {
private:
sem_t sem_1, sem_2;
public:
Foo() {
sem_init(&sem_1, 0, 0);
sem_init(&sem_2, 0, 0);
}
void first(function<void()> printFirst) {
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
//以原子操作的方式为将信号量增加1
sem_post(&sem_1);
}
void second(function<void()> printSecond) {
sem_wait(&sem_1);
// printSecond() outputs "second". Do not change or remove this line.
printSecond();
//以原子操作的方式为将信号量增加1
sem_post(&sem_2);
}
void third(function<void()> printThird) {
sem_wait(&sem_2);
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
};