「東雲 忠太郎」の平凡な日常のできごと

「東雲 忠太郎」の平凡な日常のできごと

2025.11.29
XML
カテゴリ: カテゴリ未分類


セマフォ(Semaphore)は、複数のタスクやスレッドが共有資源に同時アクセスするのを制御する同期機構です。
マルチタスクやマルチスレッド環境で必須の概念で、排他制御やリソース管理に使われます。
■ セマフォの基本概念
共有資源へのアクセス回数をカウントする整数値を持つ
値が 1 の場合 → 排他制御(1タスクだけがアクセス可能)
値が >1 の場合 → 同時に複数タスクがアクセス可能
値が 0 の場合 → 待機状態(タスクはブロックされる)
■ セマフォの種類
1. バイナリセマフォ (Binary Semaphore)
値は 0 または 1 だけ
ミューテックスと同様に排他制御に使える
「1なら資源使用可能」「0なら待機」
イメージ
初期値 = 1
タスクA: セマフォ取得 → 値 = 0
タスクB: セマフォ取得 → 待機
タスクA: セマフォ解放 → 値 = 1
タスクB: 待機解除 → 値 = 0
2. カウントセマフォ (Counting Semaphore)
値が 0 以上の整数
資源が複数ある場合に使用
例えばプリンターが3台ある場合 → 初期値 = 3
イメージ
初期値 = 3
タスクA取得 → 値=2
タスクB取得 → 値=1
タスクC取得 → 値=0
タスクD取得 → 待機
タスクA解放 → 値=1 → タスクD待機解除
■ セマフォの主な操作
Wait / Take / P操作
セマフォ値が 1以上なら値を減らして通す
0ならブロックされる(待機)
Signal / Give / V操作
セマフォ値を増やす
待機中のタスクがあれば起こす
■ セマフォの用途
✅ 排他制御(Mutual Exclusion)
複数タスクから同じハードウェア・データ構造にアクセスする場合
例:I²C通信バス、共有メモリ
✅ リソース管理
同時に使える資源の数を管理
例:プリンタ、DB接続プール、センサー数
✅ タスク間同期
あるタスクがイベントを待っている間、セマフォで通知
例:割り込みハンドラからタスクを起こす
■ 注意点
デッドロックに注意
複数タスクが互いにセマフォ待ちになると進まなくなる
優先度逆転問題
高優先度タスクが低優先度タスクの解放待ちで遅れることがある
カウントの初期値設定が重要
■ 簡単な例(FreeRTOS風疑似コード)
SemaphoreHandle_t xSemaphore;
void setup() {
    xSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(xSemaphore); // 初期値 = 1
}
void TaskA(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
        // 共有資源を使用
        I2C_ReadSensor();
        xSemaphoreGive(xSemaphore);
    }
}
void TaskB(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
        // 共有資源を使用
        I2C_WriteSensor();
        xSemaphoreGive(xSemaphore);
    }
}
上記例では、I²C通信を複数タスクから排他的に扱えるようになっています。
まとめ
セマフォは「共有資源へのアクセス回数を管理するカウンタ」
バイナリセマフォ → 排他制御
カウントセマフォ → 複数資源管理
デッドロック・優先度逆転に注意
RTOSやマルチスレッド環境で広く利用される





お気に入りの記事を「いいね!」で応援しよう

Last updated  2025.11.29 12:51:14


【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! -- / --
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
X

© Rakuten Group, Inc.
X
Mobilize your Site
スマートフォン版を閲覧 | PC版を閲覧
Share by: