[解決済み] シグナルハンドラでprintfを使用しないようにするには?
質問
以下
printf
はリエントラントではないので、シグナルハンドラで使うのは安全でないはずです。しかし、私は多くのサンプルコードで
printf
をこのように使っているコード例をたくさん見ました。
そこで質問ですが、どのような場合に
printf
の使用を避ける必要があるのはどのような場合か、また、推奨される代替手段はあるか?
どのように解決するのですか?
フラグ変数を使用して、シグナルハンドラ内でそのフラグを設定し、そのフラグに基づき
printf()
関数を呼び出すことができます。
などのすべての関数を呼び出すことは安全ではありません。
printf
のようなすべての関数をシグナルハンドラ内から呼び出すことは安全ではありません。
便利なテクニックは、シグナルハンドラで
flag
を設定し、次にその
flag
をチェックし、必要ならメッセージを表示します。
以下の例では、シグナルハンドラ ding() がフラグをセットしていることに注意してください。
alarm_fired
を 1 に設定し、メイン関数で
alarm_fired
の値が調べられ、条件付きで正しくprintfが呼び出されます。
static int alarm_fired = 0;
void ding(int sig) // can be called asynchronously
{
alarm_fired = 1; // set flag
}
int main()
{
pid_t pid;
printf("alarm application starting\n");
pid = fork();
switch(pid) {
case -1:
/* Failure */
perror("fork failed");
exit(1);
case 0:
/* child */
sleep(5);
kill(getppid(), SIGALRM);
exit(0);
}
/* if we get here we are the parent process */
printf("waiting for alarm to go off\n");
(void) signal(SIGALRM, ding);
pause();
if (alarm_fired) // check flag to call printf
printf("Ding!\n");
printf("done\n");
exit(0);
}
<サブ 参照 はじめてのLinuxプログラミング 第4版 この本では、まさにあなたのコードが説明されています(あなたが望むもの)、第11章:プロセスとシグナル、ページ484 の
さらに、ハンドラ関数は非同期に呼び出される可能性があるため、ハンドラ関数を書く際には特別な注意を払う必要があります。つまり、ハンドラはプログラムのどの時点でも、予測不可能に呼び出される可能性があるのです。もし、2つのシグナルが非常に短い間隔で到着した場合、1つのハンドラが別のハンドラの中で実行される可能性があります。そして、より良いプラクティスと考えられているのが
volatile sigatomic_t
このタイプは常にアトミックにアクセスされ、変数へのアクセスの中断に関する不確実性を避けることができます。(読む
アトミックデータアクセスとシグナルハンドリング
を参照してください)。
読む
シグナルハンドラの定義
を読んでください。
signal()
または
sigaction()
のような関数があります。
で許可された関数のリスト
マニュアルページ
この関数は、シグナルハンドラ内で呼び出しても問題ありません。
関連
-
[解決済み] Linuxで特定のテキストを含むすべてのファイルを検索するにはどうすればよいですか?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] ワイルドカードマッチングに基づいて、現在のフォルダとサブフォルダ内のすべてのファイルを再帰的に検索するにはどうすればよいですか?
-
[解決済み] Linux上で動作するC++コードのプロファイリングを行うにはどうすればよいですか?
-
[解決済み] エクスポートされた環境変数を削除する方法を教えてください。
-
[解決済み] すべてのディレクトリとサブディレクトリを再帰的にgrepするにはどうしたらいいですか?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] Project Eulerとの速度比較。CとPythonとErlangとHaskellの比較
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
_CRT_SECURE_NO_WARNINGS エラーメッセージ、解決方法
-
g++が内部・外部コマンドソリューションとして認識されない、MinGWを初めて使うときの落とし穴
-
[解決済み] ソケットアクセプト - "開かれているファイルが多すぎる"
-
[解決済み] Cコードの単体テスト【終了しました
-
[解決済み] longをフォーマットするprintfの引数は何ですか?
-
[解決済み] printfにおけるdoubleの正しい書式指定子
-
[解決済み] C言語でオブジェクト指向のコードを書くとしたら、どのようにすればよいのでしょうか?[クローズド]
-
[解決済み] C言語でファイルが存在するかどうかを確認する最も良い方法は何ですか?
-
[解決済み】C言語でintをstringに変換する方法は?
-
[解決済み] Linuxのitoa関数はどこにあるのですか?