1

(ここにこ​​の質問へのフォローアップがあります

Linux用のPythonベースのInitシステムを作成しようとしていますが、Pythoninitスクリプトへのシグナルの取得に問題があります。「man2kill」ページから:

The only signals that can be sent to process ID 1, the init process,  are  those for which init has explicitly installed signal handlers.

PythonベースのInitには、テスト関数とその関数を呼び出すためのシグナルハンドラーのセットアップがあります。

def SigTest(SIG, FRM):
    print "Caught SIGHUP!"

signal.signal(signal.SIGHUP, SigTest)

別のTTY(initスクリプトは別のttyでshを実行します)からシグナルを送信すると、それは完全に無視され、テキストが印刷されることはありません。kill -HUP 1

この問題を見つけたのは、Python initが子プロセスを死ぬときに刈り取るための刈り取り関数を作成したためですが、それらはすべてゾンビであり、PythonがSIGCHLDシグナルを取得していないことを理解するのに時間がかかりました。私の環境が正常であることを確認するために、私はフォークするCプログラムを作成し、子供にPID 1に信号を送信させ、それが登録されました。

が機能していない場合にシステムが確認するシグナルハンドラーをインストールするにはどうすればよいsignal.signal(SIG, FUNC)ですか?

ctypesを使用してハンドラーをCコードに登録し、それが機能するかどうかを確認しますが、可能であれば、純粋なPythonの答えを使用します。

アイデア?

(私はプログラマーではありません、私は本当にここで頭を抱えています:p)

以下のテストコード...

import os
import sys
import time
import signal


def SigTest(SIG, FRM):
    print "SIGINT Caught"

print "forking for ash"
cpid = os.fork()
if cpid == 0:
    os.closerange(0, 4)
    sys.stdin = open('/dev/tty2', 'r')
    sys.stdout = open('/dev/tty2', 'w')
    sys.stderr = open('/dev/tty2', 'w')
    os.execv('/bin/ash', ('ash',))

print "ash started on tty2"

signal.signal(signal.SIGHUP, SigTest)

while True:
    time.sleep(5.0)
4

1 に答える 1

1

シグナルハンドラーは主にPythonで動作します。しかし、いくつかの問題があります。1つは、インタープリターがバイトコードインタープリターに再入力するまでハンドラーが実行されないことです。プログラムがC関数でブロックされている場合、シグナルハンドラは戻るまで呼び出されません。待っている場所にコードを表示しません。signal.pause()を使用していますか?

もう1つは、システムコールを使用している場合、singalハンドラーが戻った後に例外が発生することです。すべてのシステムコールを再試行ハンドラーでラップする必要があります(少なくともLinuxでは)。

あなたがinitの置き換えを書いているのは興味深いことです...それはプロセスマネージャーのようなものです。proctoolsコードは、SIGCHLDを処理するため、興味があるかもしれません。

ちなみに、このコード:

import signal

def SigTest(SIG, FRM):
    print "SIGINT Caught"

signal.signal(signal.SIGHUP, SigTest)

while True:
    signal.pause()

私のシステムでは動作しますか。

于 2011-04-29T01:58:11.093 に答える