import multiprocessing
import signal
import time
TIMEOUT = 10
webuitest = None
isrunning = False
class PlanExecTimeoutException(Exception):
pass
def handle_excels():
global webuitest
global isrunning
def handle_signal(signum, frame):
print('handle_signal')
global webuitest
global isrunning
print('xxxx', isrunning, webuitest)
# 设置信号处理函数
signal.signal(signal.SIGTERM, handle_signal)
# webuitest = '000A'
# isrunning = True
for i in range(1000000):
print('执行任务:', i)
print('业务执行时,全局参数:', isrunning, webuitest)
time.sleep(1)
def execute_with_timeout(func, args=()):
process = multiprocessing.Process(target=func, args=args) # 创建子进程执行函数
process.start() # 启动子进程
process.join(TIMEOUT) # 等待子进程执行完毕或超时
if process.is_alive():
process.terminate() #
process.kill() # 在linux操作系统下,执行process.terminate()会传递终止信号给到子进程,但是不会终止子进程,在windows系统下直接终止子进程,子进程中注册的signal.signal(signal.SIGTERM, handle_signal)handle_signal都来不及执行
process.join() # 等待子进程完全终止
raise PlanExecTimeoutException("Function execution timed out.")
def run_demon():
global isrunning
global webuitest
while True:
print('a:', isrunning, webuitest)
try:
execute_with_timeout(handle_excels)
except PlanExecTimeoutException as e:
print('捕获执行超时,重置参数')
isrunning = 'ooooooooooooooooo'
webuitest = '00000000000000000'
time.sleep(3)
if __name__ == '__main__':
run_demon()
以上代码在linux下和windows下执行会出现,子进程使用的全局变量不同的情况。
windows下,子进程启动时使用的全局变量永远是定义时的值。
linux下,子进程启动时使用的全局变量是当前的值。
这里AI给出的解释是:
在多进程编程中,Windows 和 Linux 对全局变量的处理方式有所不同。
在 Linux 中,使用 multiprocessing
模块创建的子进程会通过进程复制(fork)的方式从父进程继承全局变量的值。因此,子进程会拥有与父进程相同的全局变量副本。当父进程修改全局变量的值时,子进程中的全局变量也会相应地发生变化。
然而,在 Windows 中,子进程的实现方式与 Linux 不同。Windows 使用了称为“起始新进程”(spawn)的机制,它会通过重新创建子进程并重新加载 Python 解释器来实现多进程。这意味着子进程会从头开始执行代码,并且不会继承父进程的全局变量的值。因此,在 Windows 中,子进程的全局变量与父进程的全局变量是完全独立的。
为了在 Windows 中实现跨进程共享数据,可以使用 multiprocessing
模块提供的共享内存或进程间通信(IPC)机制,如 multiprocessing.Value
、multiprocessing.Array
、multiprocessing.Queue
等。这些机制允许在父进程和子进程之间共享数据,并确保对数据的修改在各个进程之间是可见的。
综上所述,在 Windows 中,父进程对全局变量的修改不会直接影响到子进程中的全局变量。如果需要在 Windows 中实现跨进程共享数据,需要使用适当的共享内存或进程间通信机制。
另外:
process.terminate()
在linux操作系统下,执行process.terminate()会传递终止信号给到子进程,但是不会终止子进程,在windows系统下直接终止子进程,子进程中注册的signal.signal(signal.SIGTERM, handle_signal)handle_signal都来不及执行
如果在linux下要终止子进程的执行,那么你需要使用process.kill()来执行。可以使用process.terminate()来向子进程中传递信号,触发子进程中使用signal.signal(signal.SIGTERM, handle_signal)注册的handle_signal函数的执行。