抱歉,您的头衔不正确。我没有足够的空间来询问以下问题:假设您运行python程序并使用派生了该过程os.fork()
。在分叉过程时,很难确定何时完成所有分叉。我需要向计算机传达所有货叉已经完成的信息,因为我需要使用关闭计算机sudo shutdown -h now
。这是因为我将使用每小时花费5美元的gcloud。如果该过程在我睡着时完成,我不想浪费35美元。
我尝试使用一个全局变量,在每次完成分支之后,python都会在字典中写下该分支实际上已经完成的信息。即使该变量是全局变量,我仍然无法使每个派生变量的值都相同。因此,我认为使用全局变量已不可行。我现在正在考虑的当前工作是定期读取终端中top命令的输出。派生完成后,该过程应终止并且不再显示在top命令中。因此,一旦只有一个运行的python进程应表示所有派生都已完成。应该花大约30分钟的时间弄清楚该怎么做,所以如果有人已经知道一些简单的方法,我宁愿不使用该方法。
我还应该注意,这将使用Google gcloud虚拟实例来完成。因此,如果gcloud已经进行了设置,可以确定fork过程是否已完成,请告诉我。
如果您坚持使用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
感谢您的帮助,但我不知道该怎么做您所建议的。另外,我不能使用
multiprocessing
它,因为它不会提高速度,而分叉却可以提高速度。因此,当我使用代码时,pid = os.fork()
如何处理pid?等等,我想我明白了。
您是什么意思,
multiprocessing
不会导致速度提高,而会导致分叉呢?multiprocessing
应该执行fork所做的相同操作(如果您不搞砸),它只会帮助您安全,轻松地进行操作。你混淆multiprocessing
与threading
?由于您没有张贴任何可重复的示例,因此很难给出具体答案。关于pid
,其结果os.fork
在子级中始终为零,在父级中非零;但在这个问题上您不需要它。我会在90分钟内回复。现在在路上。
实际上,看看我的笔记多处理程序确实可以加快程序的速度。但是,使用多处理程序重写我的程序似乎需要30分钟,并且鉴于分叉已经可以工作,我不需要这样做。我的新问题是我无法检查进程是否存在。我杀死了该程序一次,第二次杀死该程序时我应该得到一个错误,但这没有发生。但这并不重要,因为我主要想在Linux上运行该程序,而现在我正在使用Mac。