在linux和windows平台启动子进程差异及终止子进程差异

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.Valuemultiprocessing.Arraymultiprocessing.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函数的执行。

相关推荐

  1. Linux进程通过“信号”终止进程

    2024-06-08 17:20:03       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-08 17:20:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-08 17:20:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-08 17:20:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-08 17:20:03       20 阅读

热门阅读

  1. HTML基础知识点

    2024-06-08 17:20:03       8 阅读
  2. Linux常用命令

    2024-06-08 17:20:03       9 阅读
  3. 音视频视频点播

    2024-06-08 17:20:03       7 阅读
  4. LeetCode 550, 380, 234

    2024-06-08 17:20:03       11 阅读
  5. KafkaStream Local Store和Global Store区别和用法

    2024-06-08 17:20:03       8 阅读
  6. Docker大学生看了都会系列(七、Dokcerfile详解)

    2024-06-08 17:20:03       11 阅读
  7. Windows系统中配置 Redis 监听特定的 IP 地址

    2024-06-08 17:20:03       10 阅读
  8. Android adb pull base.apk 方法介绍

    2024-06-08 17:20:03       8 阅读
  9. 【VVC】类和编码树了解

    2024-06-08 17:20:03       6 阅读
  10. golang优雅代码【lock实现】

    2024-06-08 17:20:03       7 阅读
  11. 堆排序---C语言

    2024-06-08 17:20:03       10 阅读
  12. [AIGC] 自定义Spring Boot中BigDecimal的序列化方式

    2024-06-08 17:20:03       8 阅读
  13. Pinia的定义及使用

    2024-06-08 17:20:03       6 阅读