大家好!
我正在尝试创建一个模拟(私人任务)意外终止多处理中的进程并恢复它。
我创建了 2 个在不同进程中运行的相同函数。 创建了一个随机选择其中一个进程并终止它的函数。 创建了一个监视正在运行的进程的功能,如果找不到所需的进程,则再次启动它。
问题是再次启动进程时,需要执行join()。但是,如果我从一个恢复进程的函数中执行一个连接,那么它就会开始等待它的完成。那些。如果此时终止了另一个进程,则恢复不会开始。
做这样的事情的正确方法是什么?
import multiprocessing as mp
import time
import random
import psutil
import os
def proc_1(timepass=1, repeat=20):
repeated = True
i = 0
while repeated:
x = random.uniform(0, timepass)
i += 1
if i < repeat:
print("Proc_1: " + str(i) + ", will fall asleep for: " + str(x))
else:
repeated = False
print("Proc_1 COMPLETED!")
break
time.sleep(x)
def proc_2(timepass=1, repeat=20):
repeated = True
i = 0
while repeated:
x = random.uniform(0, timepass)
i += 1
if i < repeat:
print("Proc_2: " + str(i) + ", will fall asleep for: " + str(x))
else:
repeated = False
print("Proc_2 COMPLETED!")
break
time.sleep(x)
def process_killer(PID_list, timepass, exclusion_list=[]):
while True:
x = random.uniform(0, timepass)
time.sleep(x)
this_process_pid = os.getpid()
this_process = psutil.Process(this_process_pid)
this_process_info_as_dict = this_process.as_dict()
parent_process_pid = this_process.ppid()
parent_process = psutil.Process(parent_process_pid)
parent_process_as_dict = parent_process.as_dict()
parent_process_children = parent_process.children(recursive=True)
child_pid_list = []
for i in range(len(parent_process_children)):
child_info_as_dict = parent_process_children[i].as_dict()
if child_info_as_dict['pid'] != this_process_pid:
child_pid_list.append(child_info_as_dict['pid'])
child_pid_list = list(set(child_pid_list) - set(exclusion_list))
# for i in range(len(child_pid_list)):
# print(f'Process_{i+1} PID: {child_pid_list[i]}')
print('\n'.join([f'Process_{i + 1} PID: {child_pid_list[i]}' for i in range(len(child_pid_list))]))
if len(child_pid_list) > 0:
if len(child_pid_list) > 1:
number = random.randint(0, len(child_pid_list) - 1)
else:
number = 0
kill_proc = psutil.Process(child_pid_list[number])
kill_process_info_as_dict = kill_proc.as_dict()
if psutil.pid_exists(kill_process_info_as_dict['pid']):
if kill_process_info_as_dict['name'] == "python.exe":
print("We kill the process with PID", kill_process_info_as_dict['pid'])
try:
kill_proc.kill()
print(f"Process with PID {kill_process_info_as_dict['pid']} killed.")
child_pid_list.remove(kill_process_info_as_dict['pid'])
except psutil.NoSuchProcess:
print(f"Process with PID {child_pid_list[number]} not found.")
def process_recovery(process_pid_list):
while True:
for i in range(len(process_pid_list)):
if psutil.pid_exists(process_pid_list[i]):
pass
# print(f'Process with PID {process_pid} is alive')
else:
print(f'Process with PID {process_pid_list[0]} is dead')
print(f'Restoring the process')
if process_pid_list[i] == process_pid_list[0]:
process = mp.Process(target=proc_1, kwargs={'timepass': 2, 'repeat': 30})
if process_pid_list[i] == process_pid_list[1]:
process = mp.Process(target=proc_2, kwargs={'timepass': 3, 'repeat': 30})
process.start()
process_pid_list[i] = process.pid
temp_str = '\n'.join(
[f'Process_{i + 1} PID: {process_pid_list[i]}' for i in range(len(process_pid_list))])
print('Recovery result:\n' + temp_str)
process.join()
time.sleep(0.2)
if __name__ == "__main__":
process_name_list = ["process_1", "process_2"]
process_1 = mp.Process(target=proc_1, kwargs={'timepass': 2, 'repeat': 30})
process_2 = mp.Process(target=proc_2, kwargs={'timepass': 3, 'repeat': 30})
process_1.start()
process_2.start()
PID_list = [process_1.pid, process_2.pid]
process_recov = mp.Process(target=process_recovery, kwargs={'process_pid_list': PID_list})
process_recov.start()
process_kill = mp.Process(target=process_killer,
kwargs={'PID_list': PID_list, 'timepass': 10, 'exclusion_list': [process_recov.pid, ]})
process_kill.start()
print("Main PID:", os.getpid())
print("Process_1 PID:", process_1.pid)
print("Process_2 PID:", process_2.pid)
print("Process_killer PID:", process_kill.pid)
process_1.join()
process_2.join()
process_kill.join()
process_recov.join()
time.sleep(5)
print("Program completed")
我试图找到有关特定主题的信息,但无法解决我的问题。
附言其实,如果我们拒绝使用process_recov这个函数,类推主进程内部死循环,问题就迎刃而解了。但是,这个选项对我来说失败了。 但我也会发布它,以便它对某人有用。
import multiprocessing as mp
import time
import random
import psutil
import os
def proc_1(timepass=1, repeat=20):
repeated = True
i = 0
while repeated:
x = random.uniform(0, timepass)
i += 1
if i < repeat:
print("Proc_1: " + str(i) + ", will fall asleep for: " + str(x))
else:
repeated = False
print("Proc_1 COMPLETED!")
break
time.sleep(x)
def proc_2(timepass=1, repeat=20):
repeated = True
i = 0
while repeated:
x = random.uniform(0, timepass)
i += 1
if i < repeat:
print("Proc_2: " + str(i) + ", will fall asleep for: " + str(x))
else:
repeated = False
print("Proc_2 COMPLETED!")
break
time.sleep(x)
def process_killer(PID_list, timepass, exclusion_list=[]):
while True:
x = random.uniform(0, timepass)
time.sleep(x)
this_process_pid = os.getpid()
this_process = psutil.Process(this_process_pid)
this_process_info_as_dict = this_process.as_dict()
parent_process_pid = this_process.ppid()
parent_process = psutil.Process(parent_process_pid)
parent_process_as_dict = parent_process.as_dict()
parent_process_children = parent_process.children(recursive=True)
child_pid_list = []
for i in range(len(parent_process_children)):
child_info_as_dict = parent_process_children[i].as_dict()
if child_info_as_dict['pid'] != this_process_pid:
child_pid_list.append(child_info_as_dict['pid'])
child_pid_list = list(set(child_pid_list) - set(exclusion_list))
# for i in range(len(child_pid_list)):
# print(f'Process_{i+1} PID: {child_pid_list[i]}')
print('\n'.join([f'Process_{i + 1} PID: {child_pid_list[i]}' for i in range(len(child_pid_list))]))
if len(child_pid_list) > 0:
if len(child_pid_list) > 1:
number = random.randint(0, len(child_pid_list) - 1)
else:
number = 0
kill_proc = psutil.Process(child_pid_list[number])
kill_process_info_as_dict = kill_proc.as_dict()
if psutil.pid_exists(kill_process_info_as_dict['pid']):
if kill_process_info_as_dict['name'] == "python.exe":
print("We kill the process with PID", kill_process_info_as_dict['pid'])
try:
process = psutil.Process(kill_process_info_as_dict['pid'])
except psutil.NoSuchProcess:
print(f"Process with PID {child_pid_list[number]} not found.")
continue
else:
kill_proc.kill()
print(f"Process with PID {kill_process_info_as_dict['pid']} killed.")
child_pid_list.remove(kill_process_info_as_dict['pid'])
def process_recovery(process_pid_list):
while True:
for i in range(len(process_pid_list)):
if psutil.pid_exists(process_pid_list[i]):
pass
# print(f'Process with PID {process_pid} is alive')
else:
print(f'Process with PID {process_pid_list[0]} is dead')
print(f'Restoring the process')
if process_pid_list[i] == process_pid_list[0]:
process = mp.Process(target=proc_1, kwargs={'timepass': 2, 'repeat': 30})
if process_pid_list[i] == process_pid_list[1]:
process = mp.Process(target=proc_2, kwargs={'timepass': 3, 'repeat': 30})
process.start()
process_pid_list[i] = process.pid
temp_str = '\n'.join(
[f'Process_{i + 1} PID: {process_pid_list[i]}' for i in range(len(process_pid_list))])
print('Recovery result:\n' + temp_str)
process.join()
time.sleep(0.2)
if __name__ == "__main__":
process_name_list = ["process_1", "process_2"]
process_1 = mp.Process(target=proc_1, kwargs={'timepass': 2, 'repeat': 30})
process_2 = mp.Process(target=proc_2, kwargs={'timepass': 3, 'repeat': 30})
process_1.start()
process_2.start()
PID_list = [process_1.pid, process_2.pid]
# process_recov = mp.Process(target=process_recovery, kwargs={'process_pid_list': PID_list})
# process_recov.start()
process_kill = mp.Process(target=process_killer,
kwargs={'PID_list': PID_list, 'timepass': 10, 'exclusion_list': []})
process_kill.start()
while True:
for i in range(len(PID_list)):
if psutil.pid_exists(PID_list[i]):
pass
# print(f'Process with PID {process_pid} is alive')
else:
print(f'Process with PID {PID_list[0]} is dead')
print(f'Restoring the process')
if PID_list[i] == PID_list[0]:
process = mp.Process(target=proc_1, kwargs={'timepass': 2, 'repeat': 30})
if PID_list[i] == PID_list[1]:
process = mp.Process(target=proc_2, kwargs={'timepass': 3, 'repeat': 30})
process.start()
PID_list[i] = process.pid
temp_str = '\n'.join(
[f'Process_{i + 1} PID: {PID_list[i]}' for i in range(len(PID_list))])
print('Recovery result:\n' + temp_str)
time.sleep(0.2)
print("Main PID:", os.getpid())
print("Process_1 PID:", process_1.pid)
print("Process_2 PID:", process_2.pid)
print("Process_killer PID:", process_kill.pid)
process_1.join()
process_2.join()
process_kill.join()
# process_recov.join()
process.join()
time.sleep(5)
print("Program completed")