時には、プロセスが受信できるすべての信号に対して少し混乱することがあります。私が理解したのは、プロセスには基本ハンドラ(信号処理)各信号に対して呼び出されますが、独自のハンドラを提供できます。sigaction()
。
私の質問は次のとおりです。各信号が送信される原因は何ですか?-s
の引数を介して実行中のプロセスに手動でシグナルを送信できることを知っていますがkill
、自然これらの信号はどのような状況で送信されますか?たとえば、いつSIGINT
出荷されますか?
また、どの信号を処理できるかについて制限がありますか?SIGSEGV
信号を処理してアプリケーションに制御を返すことは可能ですか?
答え1
プロセスコールに加えてkill(2)
、一部シグナルさまざまな状況でカーネル(または時にはプロセス自体)によって送信されます。
- 端末ドライバは、様々なイベントに対応する信号を送信する。
- キー押下通知:
SIGINT
(メインループに戻ります) On Ctrl+ C、SIGQUIT
(すぐに終了してください)on Ctrl+ \、SIGTSTP
(しばらくしてください)Ctrl+ Z。次のコマンドを使用してキーストロークを変更できますstty
注文する。 SIGTTIN
そしてSIGTTOU
バックグラウンド・プロセスが制御端末から読み書きするときに送信されます。SIGWINCH
端末ウィンドウのサイズが変更されたことを示す信号を送信します。SIGHUP
端末が消えたことを知らせます(歴史的にモデムが消えたため)。時間ウォン戻る(これは通常、端末エミュレータウィンドウを閉じたためです)。
- キー押下通知:
- 一部のプロセッサトラップは信号を生成できます。詳細はアーキテクチャとシステムによって異なります。以下は一般的な例です。
- 多くの信号は、特定のシステムイベントが発生したことをターゲットプロセスに通知します。
SIGALRM
設定されたタイマーの有効期限が切れたことをプロセスに通知します。タイマーは次のように設定できます。alarm
、setitimer
他の人。SIGCHLD
子プロセスの1つが終了したことをプロセスに通知します。SIGPIPE
foo | bar
読み取り側が閉じている間にプロセスがパイプに書き込もうとしたときに生成されます(実行して終了するとbar
終了foo
するという概念ですSIGPIPE
)。SIGPOLL
(とも呼ばれるSIGIO
)ポーリング可能なイベントが発生したことをプロセスに通知します。 POSIXは、以下を介して登録されたポーリング可能なイベントを指定します。I_SETSIG
ioctl
。多くのシステムでは、次のすべてのファイル記述子でポーリング可能なイベントを許可します。O_ASYNC
fcntl
バナー。関連信号はSIGURG
、機器に緊急データを通知する(登録I_SETSIG
ioctl
) またはソケット。- 一部のシステムでは
SIGPWR
すべてのプロセスに転送されるときアップ停電が差し迫ったことを示します。
このリストは完全なものではありません。標準信号は次のように定義されます。signal.h
。
ほとんどの信号はアプリケーションによってキャプチャおよび処理(または無視)できます。キャプチャできない唯一のポータブル信号は2つでした。SIGKILL
(ただ死ぬ)とSTOP
(実行を中止します)。
SIGSEGV
(セグメンテーションエラー)と彼のいとこSIGBUS
(バスエラー)捕まえるかもしれませんが、自分がしていることを実際に知らない限り悪い考えです。これをキャプチャするための一般的なアプリケーションは、スタックトレースやその他のデバッグ情報を印刷することです。より進化したアプリケーションは、ある種のプロセス内メモリ管理を実装するか、仮想マシンエンジンで誤ったコマンドを見つけることです。
最後に、信号ではないことについて言及します。端末から入力を読み取るプログラムの行の先頭でCtrl+を押すと、プログラムはD入力ファイルの終わりに達したことを知らせます。これは信号ではありません。入力/出力APIを介して送信されます。 Like Ctrl+CとFriendsを使用してボタンを設定できますstty
。
答え2
まず、2番目の質問に答えてください。アプリケーションではキャプチャできませんが、他のすべてのシグナルはキャプチャできますSIGSTOP
。このプロパティはデバッグに役立ちます。たとえば、正しいライブラリサポートを使用すると、スタックトレースを受け取り、生成して表示できます。セグフォルトが発生した位置。SIGKILL
SIGSEGV
SIGSEGV
man 7 signal
Linuxコマンドラインに入力すると、各信号の機能(Linuxの場合)の正式な説明が得られます。http://linux.die.net/man/7/signal同じ情報がありますが、テーブルを読むのは難しいです。
しかし、シグナルの経験がなければ、簡単な説明でシグナルが実際にどのように機能するかを理解することは困難です。これの説明は次のとおりです。
キーボードでトリガー
SIGINT
を打ったときに発生しますCTRL+C
。SIGQUIT
によってトリガーされ、CTRL+\
コアをダンプします。SIGTSTP
をクリックするとプログラムが一時停止しますCTRL+Z
。とは異なり、プログラムが中断される前に端末を安全な状態にリセットする機会をSIGSTOP
提供するキャッチ可能です。vi
端末相互作用
SIGHUP
(「hangup」)は、プログラムの実行中にxtermが閉じられたとき(または端末から切断されたとき)に発生します。SIGTTIN
SIGTTOU
プログラムがバックグラウンドで実行されている間に端末から読み書きしようとすると、プログラムを停止します。このようなことが起こるためには、SIGTTOU
プログラムが/dev/tty
デフォルトのstdoutだけでなくに書かなければならないと思います。
CPU例外トリガー
これは、プログラムが何か間違った操作を試みていることを意味します。
SIGILL
不正または不明なプロセッサ命令を示します。たとえば、プロセッサI / Oポートに直接アクセスしようとすると、これが発生する可能性があります。SIGFPE
プログラムがゼロに分割しようとした可能性が高いハードウェア数学エラーを示します。SIGSEGV
プログラムがマップされていないメモリ領域にアクセスしようとしていることを意味します。SIGBUS
これは、プログラムが異なる方法でメモリに誤ってアクセスしたことを意味します。この概要では詳しく説明しません。
プロセス相互作用
SIGPIPE
パイプリーダーがパイプの端を閉じてからパイプに書き込もうとすると、これが発生します。望むよりman 7 pipe
。SIGCHLD
SIGSTOP
これは、作成した子プロセスが終了または中断されたときに発生します(または同様の方法で)。
セルフシグナリングに便利
SIGABRT
通常、abort()
この関数を呼び出すプログラムが原因で発生し、デフォルトではコアダンプが発生します。一種の「パニックボタン」と同じです。SIGALRM
これは、カーネルが指定された時間(秒)後にプログラムに渡すようにするalarm()
システムコールによって発生します。とをSIGALRM
参照してください。man 2 alarm
man 2 sleep
SIGUSR1
そして、SIGUSR2
プログラムが望む方法で使用してください。プロセス間シグナルを送信するのに便利です。
管理者が送信しました
これらの信号は通常コマンドプロンプトで送信されますkill
。fg
bg
SIGCONT
SIGKILL
止められない信号ですSIGSTOP
。 1つ目は常にプロセスを即座に終了し、2つ目はプロセスを中断します。SIGCONT
一時停止したプロセスを再開します。SIGTERM
はい、キャプチャ可能なバージョンですSIGKILL
。
答え3
これは、以下を含むすでに提供されている他の回答に追加または追加されます。
ほとんどの信号の詳細については、Wikipediaを参照してください。https://en.wikipedia.org/wiki/Signal_(IPC)
最も一般的な信号の1つは、SIGINT
プロセスの実行中に+をINT
押して送信されるプログラム割り込み信号です。CtrlC
~からウィキペディア記事以上:
SIGINT
「信号中断」
SIGINT
この信号は、ユーザーがプロセスを中断したいときにプロセスを制御するターミナルによってプロセスに送信されます。これは通常Ctrl+を押して開始されますが、一部のシステムではC「削除」文字またはキーを使用できます。 [12]"break"
実行中のプロセスに手動でシグナルを送信する方法
[実行中のプロセスに]さまざまな信号が送信される原因は何ですか?
信号を送信する他のプログラムやキー入力に加えてあなたはそうです!
走ったりkill -l
kill --list
実行中のプロセスに送信できるすべてのシグナルのリスト。
実行と出力の例:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
たとえば、「警告」信号(たとえばSIGALRM
、ALRM
または信号番号14
)を送信するには、次のいずれかを実行できます。
kill -SIGALRM <pid>
kill -ALRM <pid>
kill -14 <pid>
kill
pidに警告信号を送信するコマンドの例123456
:
kill -SIGALRM 123456
kill -ALRM 123456
kill -14 123456
以下を読んでくださいman kill
(ハイライトを追加):
説明する
基本信号
kill
はですTERM
。利用可能な信号を使用-l
または-L
一覧表示します。特に有用な信号にはHUP
、、、、およびINT
があります。KILL
STOP
CONT
0
-9
代替信号は、-SIGKILL
または3つの方法で指定できます-KILL
。 負のPID値は、プロセスグループ全体を選択するために使用できます。ps
コマンド出力のPGID列を参照してください。 PID-1
は特別です。終了プロセス自体とinitを除くすべてのプロセスを表します。
到着興味のあるプロセスID(pid)を見つけます。、以下を実行してください。
ps aux | grep "some program name string or regular expression to search for"
出力ラインで一番左の信号番号を探します。左から2番目の列はPID(プロセスID)番号です。
プログラムで信号をキャッチする方法
1. バッシュから
「トラップ」、またはカスタム信号をキャプチャし、それに応じてアクションを実行します。強く打つSIGALRM
プログラムでは次のことができます(信号をキャプチャします)。
trap <any_comand_to_run_when_signal_is_received> SIGALRM
以下は、カスタムbashプログラムでCtrl+ C"割り込み"(SIGINT
またはINT
セマフォ)信号をキャプチャするために使用される一般的なトラップです。2
# Trap the Ctrl + C SIGINT signal from this point onward in the bash program so
# that whenever the user presses Ctrl + C, this program prints `Ctrl + C` and
# then exits with exit code 2 (change that to any exit code you'd like to
# return when Ctrl + C is pressed!).
trap 'printf "%s\n" " Ctrl + C"; exit 2' SIGINT
望むより:サーバー障害:Bashループ - コマンドでControl-Cを押したときにループをどのように停止しますか?。
2. CとC++で
Linuxでは、CまたはC ++で指定された信号をキャプチャしてそれを処理するには、sigaction()
(好ましくは)またはsignal()
(あまり良くありませんが、C標準の一部)を使用できます。詳細な使用例と一緒に、これに対する包括的な答えを参照してください。スタックオーバーフロー:sigactionとsignalの違いは何ですか?
Bashでのkill
シグナルの送信(通過)とキャッチ(通過)の例trap
次のプログラムは、trap
コマンド(信号の受信とその動作)とkill
コマンド(プロセスに信号を送る)を検索します。
- このbashムカデゲームを見てください:
- Ubuntuに尋ねてください:コマンドラインスネークゲーム?
- 私のeRCAGuy_hello_worldリポジトリはここにあります:ムカデゲーム.sh