工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C++シグナル処理をマスター:安全な割り込み管理とクリーンなプログラム終了

シグナルとは、オペレーティングシステムによってプロセスに送られる割り込みであり、プログラムを予期せず終了させる可能性があります。UNIX、Linux、macOS、WindowsシステムでCtrl+Cを押すことで割り込みを生成できます。

プログラムで捕捉できないシグナルもありますが、<csignal>ヘッダーファイルで定義されている以下のシグナルはプログラムで捕捉し、適切なアクションを取ることができます。

番号シグナルと説明
1SIGABRT
abort呼び出しなどによるプログラムの異常終了
2SIGFPE
ゼロ除算やオーバーフローなどの不正な算術演算
3SIGILL
不正な命令の検出
4SIGINT
インタラクティブなアテンションシグナルの受信(Ctrl+C)
5SIGSEGV
ストレージへの無効なアクセス(セグメンテーション違反)
6SIGTERM
プログラムへの終了要求

signal()関数

C++のシグナル処理ライブラリは、予期せぬイベントを捕捉するためのsignal関数を提供します。構文は以下の通りです。

void (*signal (int sig, void (*func)(int)))(int);

簡単に言うと、この関数は2つの引数を取ります:シグナル番号を表す整数と、シグナルハンドラ関数へのポインタです。

以下はsignal()関数を使ってSIGINTシグナルを捕捉する簡単なC++プログラムです。プログラムで捕捉したいシグナルがあれば、signal関数でそのシグナルを登録し、シグナルハンドラと関連付ける必要があります。

#include <iostream>
#include <csignal>
using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt signal (" << signum << ") received.\n";
    // クリーンアップ処理をここに記述
    // プログラム終了
    exit(signum);
}

int main() {
    // SIGINTシグナルとハンドラを登録
    signal(SIGINT, signalHandler);
    
    while(1) {
        cout << "Going to sleep...." << endl;
        sleep(1);
    }
    return 0;
}

上記コードをコンパイルして実行すると、以下のような結果になります。

Going to sleep....
Going to sleep....
Going to sleep....

ここでCtrl+Cを押してプログラムを中断すると、シグナルを捕捉して以下のように出力して終了します。

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

raise()関数

raise()関数を使ってシグナルを生成することもできます。この関数は整数のシグナル番号を引数に取り、以下の構文を持ちます。

int raise (signal sig);

ここでsigは送信するシグナル番号です:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUPなど。以下はraise()関数を使って内部的にシグナルを発生させる例です。

#include <iostream>
#include <csignal>
using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt signal (" << signum << ") received.\n";
    // クリーンアップ処理をここに記述
    // プログラム終了
    exit(signum);
}

int main() {
    int i = 0;
    // SIGINTシグナルとハンドラを登録
    signal(SIGINT, signalHandler);
    
    while(++i) {
        cout << "Going to sleep...." << endl;
        if(i == 3) {
            raise(SIGINT);
        }
        sleep(1);
    }
    return 0;
}

上記コードをコンパイルして実行すると、以下の結果が出力され自動的に終了します。

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

C言語

  1. C++データ型完全ガイド:基本型、修飾子、ベストプラクティス
  2. C++演算子完全ガイド:算術・代入・関係・論理・ビット演算子と実例
  3. C++コメント完全ガイド:読みやすく保守しやすいコードのためのベストプラクティス
  4. C++クラステンプレート完全ガイド:実践的なジェネリックプログラミング
  5. C言語 ファイル入出力: fopen, fprintf, fread, fseek をマスターする
  6. C++例外処理をマスター:try、catch、throwの実践例
  7. C言語エラーハンドリングのマスター:ベストプラクティスとテクニック
  8. C++プログラミング言語:概要と主要機能
  9. C++定数とリテラル完全解説:型、構文、ベストプラクティス
  10. C++演算子完全ガイド:種類、使い方、ベストプラクティス
  11. C++数値型完全ガイド:実践的な使い方と数学関数