温馨提示:本文翻译自stackoverflow.com,查看原文请点击:gcloud - What is the easiest way to determine all forks are done in Python
gcloud python

gcloud - 确定所有派生在Python中完成的最简单方法是什么

发布于 2020-04-16 13:23:26

抱歉,您的头衔不正确。我没有足够的空间来询问以下问题:假设您运行python程序并使用派生了该过程os.fork()在分叉过程时,很难确定何时完成所有分叉。我需要向计算机传达所有货叉已经完成的信息,因为我需要使用关闭计算机sudo shutdown -h now这是因为我将使用每小时花费5美元的gcloud。如果该过程在我睡着时完成,我不想浪费35美元。

我尝试使用一个全局变量,在每次完成分支之后,python都会在字典中写下该分支实际上已经完成的信息。即使该变量是全局变量,我仍然无法使每个派生变量的值都相同。因此,我认为使用全局变量已不可行。我现在正在考虑的当前工作是定期读取终端中top命令的输出。派生完成后,该过程应终止并且不再显示在top命令中。因此,一旦只有一个运行的python进程应表示所有派生都已完成。应该花大约30分钟的时间弄清楚该怎么做,所以如果有人已经知道一些简单的方法,我宁愿不使用该方法。

我还应该注意,这将使用Google gcloud虚拟实例来完成。因此,如果gcloud已经进行了设置,可以确定fork过程是否已完成,请告诉我。

查看更多

提问者
logic1976
被浏览
22
Amadan 2020-02-04 16:09

如果您坚持使用os.fork,我相信最好的方法是使用signal陷阱SIGCHLD(每当子进程终止时发送到父进程的信号)。每次分叉时增加一个计数器,每次捕获时递减并检查零SIGCHLD由于变量仅在父进程的主线程中,因此没有同步问题。

如果它对您有用,那么更好的方法是使用multiprocessing模块而不是os.fork,因为它将为您做很多记帐工作(以及解决许多其他重复出现的问题,例如进程间通信)。

编辑:这是该os.fork案例的一个玩具示例

import os
import sys
import random
import signal
import time

def do_something(i):
    print(f"Process {i} starting")
    time.sleep(random.uniform(1, 10))
    print(f"Process {i} ending")
    sys.exit()

running = 0

for i in range(10):
    if os.fork():          # in parent fork (we got the child PID)
        running += 1
    else:                  # in child fork (we got zero)
        do_something(i)

def chld_handler(signo, frame):
    global running
    running -= 1
    print(f"A child died. {running} remain.")
    if not running:
        print("All dead. Exiting.")
        sys.exit()

signal.signal(signal.SIGCHLD, chld_handler)

while True: time.sleep(1) # loop forever