C言語

【C言語】第9章第5回:シグナルと割り込み処理

シグナルと割り込み処理は、C言語を使用してイベントドリブンプログラムを設計する際に重要な役割を果たします。本記事では、その基本と応用を学びます。

0. 記事の概要

この記事を読むメリット

  • イベントドリブンプログラミングの基礎理解:シグナルと割り込み処理の概念を学びます。
  • 実践的なスキル:シグナル処理を用いたプログラム設計方法を習得します。
  • 応用力の向上:割り込み処理を使用したリアルタイムシステムの基礎を理解します。

この記事で学べること

  • シグナルと割り込み処理の基本概念
  • シグナルハンドラの実装
  • 割り込み処理の応用例

1. シグナルの基本

1.1 シグナルとは?

シグナルは、オペレーティングシステムがプロセスに通知を送るための仕組みです。特定のイベント(例:ユーザーの中断、タイマーの期限切れなど)が発生すると、シグナルが送られます。

1.2 主なシグナルの種類

シグナル意味
SIGINTプログラムの中断(Ctrl+C)
SIGTERMプログラムの終了要求
SIGKILL強制終了
SIGALRMタイマーの期限切れ

2. シグナルハンドラの実装

2.1 シグナルハンドラの基本構造

#include <stdio.h>
#include <signal.h>

// シグナルハンドラ
void handleSignal(int sig) {
    printf("Signal %d received.\n", sig);
}

int main() {
    signal(SIGINT, handleSignal); // Ctrl+C をキャッチ
    while (1) {
        printf("Running...\n");
        sleep(1);
    }
    return 0;
}
動作解説
  1. ハンドラの登録:`signal`関数を使用して`SIGINT`をキャッチします。
  2. ハンドラの動作:ユーザーがCtrl+Cを押すと、`handleSignal`が呼び出されます。

2.2 カスタムシグナルハンドラの設計

複数のシグナルを処理する場合、条件分岐を使用して異なる処理を実行できます。

#include <stdio.h>
#include <signal.h>

void handleSignal(int sig) {
    if (sig == SIGINT) {
        printf("SIGINT received. Exiting program.\n");
        exit(0);
    } else if (sig == SIGALRM) {
        printf("SIGALRM received. Timer expired.\n");
    }
}

int main() {
    signal(SIGINT, handleSignal);
    signal(SIGALRM, handleSignal);

    alarm(5); // 5秒後にSIGALRM送信
    while (1) {
        printf("Waiting for signal...\n");
        sleep(1);
    }
    return 0;
}

3. 割り込み処理の基本

3.1 割り込み処理とは?

割り込み処理は、ハードウェアやソフトウェアからのイベントが発生した際に、通常のプログラムフローを中断して特定の処理を実行する仕組みです。

3.2 割り込み処理の応用例

  • リアルタイムデータ収集
  • デバイス間の通信管理
  • タイミング依存の操作(例:一定時間ごとのタスク実行)

4. 練習問題

以下の課題に挑戦して、シグナルと割り込み処理の理解を深めましょう。

  1. Ctrl+Cを押したときにプログラムが特定のメッセージを表示するシグナルハンドラを実装してください。
  2. タイマーの期限切れ時にメッセージを表示するプログラムを作成してください。
  3. 複数のシグナルを処理するプログラムを設計してください。

5. 練習問題の解答と解説

問2の解答

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handleAlarm(int sig) {
    printf("Timer expired. Signal %d received.\n", sig);
}

int main() {
    signal(SIGALRM, handleAlarm);
    alarm(3); // 3秒後にSIGALRM送信

    while (1) {
        printf("Waiting...\n");
        sleep(1);
    }
    return 0;
}

このプログラムでは、3秒後に`SIGALRM`シグナルが送信され、ハンドラが実行されます。

6. まとめ

本記事では、シグナルと割り込み処理の基本概念と実装方法について学びました。次回は、リアルタイム処理における応用例を掘り下げます。