首页 > 解决方案 > 在 python 中处理 USR1 信号

问题描述

我对 python 中的信号还是很陌生,我想知道我的程序有什么问题。

我有 prog1.py

import signal 
import os
import time


pid = os.getpid()

def receive(signum, stack):
    print("Received",signum)

signal.signal(signal.SIGUSR1, receive)

print("PID is : ",pid)

while True:
    print("Waiting")
    time.sleep(3)

prog2.py

from prog1 import pid

n = 0

while True:
    n = n + 1
    print(n)
    if ( n % 10 == 0):
        os.kill(pid, signal.SIGUSR1)

所以我在这里要做的是每次 n 可以被 10 整除时向 prog1.py 发送一个 USR1 信号。

所以首先我运行 prog1.py,这样我就可以提取它的 pid 并将它传递给 prog2。然后我运行 prog2.py 以获取 prog1 的 pid,并在每次 n 可被 10 整除时向 prog1 发送 USR1 信号。但这里发生的情况不同:运行 prog1 后,我得到此输出(除外):

PID is :  15355
Waiting
Waiting
Waiting
Waiting
...

但是当我运行 prog2 时,我得到了这个输出(我没想到):

PID is :  15629
Waiting
Waiting
Waiting
Waiting
...

我在这里做错了什么?

标签: python-3.xlinuxsignals

解决方案


如果您不想从 prog2.py 分叉 prog1.py 但独立运行它们,则必须将 prog1.py 的 PID 保存在文件系统的某个位置并让 prog2.py 读取它。此外,您将很快了解到print()在信号处理程序中运行是一个坏主意 - 信号处理程序应该非常快并运行可重入函数。归根结底,代码可能如下所示:

程序1.py:

#!/usr/bin/env python3

import signal
import os
import time


pid = os.getpid()

with open("/tmp/prog1.pid", "w") as pidfile:
    pidfile.write(f"{pid}\n")

GOT = 0


def receive(signum, stack):
    global GOT
    GOT = 1


signal.signal(signal.SIGUSR1, receive)

print("PID is : ", pid)

while True:
    if GOT == 1:
        print("Received signal.SIGUSR1")
        GOT = 0

    print("Waiting")
    time.sleep(3)

程序2.py:

#!/usr/bin/env python3

import os
import signal

with open("/tmp/prog1.pid", "r") as pidfile:
    prog1_pid = int(pidfile.readline())

N = 0

while True:
    N = N + 1
    if N % 10 == 0:
        os.kill(prog1_pid, signal.SIGUSR1)

推荐阅读