Mac OS X (私は 10.6 を持っています) のプロセス内からそのプロセスにリソース制限を設定する方法を理解しようとしています。CentOS では、次のテスト プログラム (python3.3) が期待どおりに動作します。
import resource
import signal
def confirm(prompt, instructions='(y)es or (n)o only, please.'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no'):
return False
print(instructions)
def handle_cpu_soft_limit(signal, frame):
print('CPU soft limit reached.')
if not confirm('Do you want to continue anyway? (y/n): '):
raise ResourceWarning()
def long_function():
a = 0
while True:
a += 1
a -= 1
def main():
# set soft limit to 1 second, hard limit to 5 seconds (CPU time)
resource.setrlimit(resource.RLIMIT_CPU, (1, 5))
# set handler for soft CPU limit signal
signal.signal(signal.SIGXCPU, handle_cpu_soft_limit)
# do some busy work
try:
long_function()
except ResourceWarning:
print('Stopping now before being forced.')
if __name__ == '__main__':
main()
プログラムは、ソフト リミット (1 秒、 に渡されるタプルの最初の要素resource.setrlimit()
) に達するまで CPU 時間を消費します。プログラムは、OS (この場合は SIGXCPU) から送信されたシグナルをキャッチし、続行するかどうかを尋ねます。CentOS (または他の Linux) では、「はい」と答えると、OS がプロセスを強制終了するハード リミット (5 秒) に達するまで、1 秒間隔で再度尋ねられます。Mac OS X では、引き続き SIGXCPU シグナルを取得して処理しますが、ハード リミットに達した場合でも、シグナルを再度取得することはなく、プロセスが強制終了されることもありません。これは、この質問の質問者が経験していたことに関連している場合と、関連していない場合があります。
Mac OS Xのマニュアル ページにsetrlimit
は、次のように記載されています。
リソース制限は、ソフト制限とハード制限として指定されます。ソフト リミットを超えると、プロセスはシグナルを受信する場合がありますが (たとえば、CPU 時間やファイル サイズを超えた場合)、ハード リミットに達するまで (またはリソース リミットを変更するまで) 実行を継続できます。
…これは実際には setrlimit の BSD 4.2 man ページからのものです。それにもかかわらず、ハードリミットに達したときにプログラムが SIGKILL を受け取ることはないようです。google と SO で mac setrlimit に関する情報を検索しましたが、有用なものはあまり見つかりませんでした。2 つの質問があります。
この動作 (具体的にはプロセスのハード制限を無視する mac os X) は意図されており、そのようにどこかに文書化されていますか? ここに私の例を Python で書きましたが、C でも同じことが起こります (要求に応じて、ここにテスト コードを投稿できます)。したがって、これは言語のバグではありません。
このコードを Linux と Mac で同じように動作させる方法はありますか? それとも、ソフト制限を Mac のハード制限のように扱うべきですか?