Pythonのシグナル処理

9,362 views
8,936 views

Published on

2011/10/15 Python Developers Festa 2011/10

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
9,362
On SlideShare
0
From Embeds
0
Number of Embeds
1,266
Actions
Shares
0
Downloads
21
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Pythonのシグナル処理

  1. 1. Pythonのシグナル処理<br />Python Developers Festa 2011/10<br />2011/10/15 AtsuoIshimoto<br />
  2. 2. お前誰よ<br />石本敦夫@無職 改め@フリータ<br />Twitter: @atsuoishimoto<br />
  3. 3. シグナルって?<br />プロセス間非同期通信の一種<br />Control+Cで実行中のプロセスが終了するのも、シグナルの仕事<br />POSIXで規定されてる->Unix/Windows等で利用可能<br />
  4. 4. Ctrl+Cを押しても止まらないプログラム<br />Cで書くと<br />void sigint_handler(intsigno) {<br />printf("received SIGINT");<br />}<br />void main() {<br /> signal(SIGINT, sigint_handler);<br /> for (;;) {<br /> sleep(1); <br /> }<br />}<br />
  5. 5. シグナルの使い方<br />Pythonでは<br />defsigint_handler(signo, frame):<br /> print "received SIGINT"<br />import signal<br />signal.signal(signal.SIGINT, sigint_handler)<br />while True:<br />signal.pause()<br />
  6. 6. ハンドラの起動まで<br />C言語版<br />シグナル通知<br />プロセス<br />シグナルハンドラ<br />(例:sigint_handler)<br />
  7. 7. ハンドラの起動まで<br />Pythonでは<br />Pythonプロセス<br />Pythonスクリプトを実行<br />シグナル通知<br />シグナル受信フラグをセット<br />時々シグナル受信フラグをチェック<br />シグナル有り<br />シグナルハンドラを実行<br />チェック周期は、sys.getcheckinterval()で決まる<br />
  8. 8. シグナルハンドラの起動タイミング<br />シグナルハンドラの起動は非同期<br />Pythonのバイトコードを一定数実行したとき<br />C API の PyErr_CheckSignals()を呼び出したとき<br />ファイルIO処理中に時々呼び出されたりする<br />シグナル発生からハンドラ起動まで、すっごい時間がかかるときがある。<br />sys.setcheckinterval()<br />時間のかかるC拡張(正規表現検索など)<br />
  9. 9. Signalとスレッド:混ぜるな危険<br />SIGTERMを受け取るまで待ち合わせする処理<br />この処理は、ev.wait()から先に進まない。<br />Event.wait()はPyErr_CheckSignals()を呼び出さないため、シグナルハンドラが呼び出されることはない。<br />ev = threading.Event()<br />def handle_term(signo, frame):<br />ev.set()<br />signal.signal(signal.SIGTERM, handle)<br />ev.wait()<br />
  10. 10. システムコールの割り込み<br />void sigint_handler(intsigno) {<br />printf("received SIGINT");<br />}<br />void main() {<br /> signal(SIGINT, sigint_handler);<br /> while (1) {<br /> read(0, 1000, buf);<br /> }<br />}<br />ishimoto@ubuntu:~$ ./a.out<br />adfkn^C^C^C^C^C^C^C^C^C^C^C^C^C^C<br />Ctrl+Cを押してもSIGINTが発生しない<br />
  11. 11. システムコールの割り込み<br />import sys, signal<br />def sigint_handler(signo, frame):<br /> print "received SIGINT"<br />signal.signal(signal.SIGINT, sigint_handler)<br />while True:<br />sys.stdin.read(100)<br />ishimoto@ubuntu:~$ python a.py<br />sadf<br />^Creceived SIGINT<br />^Creceived SIGINT<br />Traceback (most recent call last):<br /> File "a.py", line 9, in <module><br />sys.stdin.read(100)<br />IOError: [Errno 4] Interrupted system call<br />SIGINTが発生する!<br />

×