如果父进程在python中崩溃,请确保子进程被杀死.解决方案必须支持所有操作系统



我有一个应用程序,其中父进程轮询服务器以获得下载作业,然后派生子进程以完成作业。这个循环一直持续到父进程处理一些作业为止。我需要确保子进程在父进程崩溃的情况下死亡。我使用python作为编程语言。另外,假设这个父进程死亡,它是由其他进程引起的。以下是一些机制-1.根据python的多处理模块-"当进程退出时,它会尝试终止其所有守护进程的子进程。"因此,它尝试但不保证。所以它不可靠。2.我可以在数据库中添加条目,映射为child_process_id->jobId,这告诉哪个子进程正在下载哪个作业。当父进程在轮询之前出现时,它会检查是否有child_process_id->jobId的条目。如果存在,它会终止具有给定child_process_id的进程,并在下一次轮询中发送jobId。当父进程突然崩溃时,我能用一种干净的方法杀死子进程吗?我需要一个兼容windows、linux和mac的解决方案。有人建议我,文件锁可以帮助我,但我不明白文件锁是如何帮助我实现这一点的。

#parent.py
import time
import subprocess
import file_lock_lib
import os
PARENT_LOCK_NAME = "ParentChildTask"
CHILD_LOCK_NAME = "ChildTask-%d"

def main():
#for running single parent process
fmutex, res = file_lock_lib.FileLock(PARENT_LOCK_NAME, True)
print("PARENT ID is =============" + str(os.getpid()))
if not res:
print("ParentProcess already running")
exit(1)
print("Spawing Child Processes")
r = subprocess.Popen(["python", "/Users/abi/PycharmProjects/osProgramming/parent_child/child.py"])
#aquire the lock for child process
c_lock, res = file_lock_lib.FileLock(CHILD_LOCK_NAME% r.pid)
import time
start_time = int(time.time())
while (int(time.time()) - start_time) < 180:
a = 1
1/0
#file_lock_lib.FileUnlock(fmutex)
if __name__ == '__main__':
main()

#file_lock.lib.py
import sys
import os
if sys.platform != 'win32':
'NOOB_IDS fcntl sysv_ipc sendmsg'
import fcntl


def FileLock(fname, nb=False):
if sys.platform == 'win32':
try:
sa = w32s.SECURITY_ATTRIBUTES()
sa.SetSecurityDescriptorDacl(True, None, False)
fmutex = win32event.CreateMutex(sa, False, fname)
except pywintypes.error as fault:
if fault.winerror == 5:
fmutex = win32event.OpenMutex(win32event.SYNCHRONIZE, False, fname)
else:
raise
if nb:
wtime = 0
else:
wtime = win32event.INFINITE
rc = win32event.WaitForSingleObject(fmutex, wtime)
if rc == win32event.WAIT_TIMEOUT or rc == win32event.WAIT_FAILED:
win32api.CloseHandle(fmutex)
return None, False
else:
if not fname.startswith('/'):
# Not an absolute path name, prefix in $HOME/.inSync
fname = os.path.join(os.getenv('HOME'), '.file_lock_lib', fname)
fdir = os.path.dirname(fname)
if not os.path.exists(fdir):
os.makedirs(fdir)
try:
fmutex = open(fname, "rb+")
except:
fmutex = open(fname, "wb+")
try:
flags = fcntl.LOCK_EX
if nb:
flags |= fcntl.LOCK_NB
fcntl.flock(fmutex.fileno(), flags)
except IOError:
return None, False
return fmutex, True

def FileUnlock(fmutex):
if sys.platform == 'win32':
win32event.ReleaseMutex(fmutex)
win32api.CloseHandle(fmutex)
else:
fcntl.flock(fmutex.fileno(), fcntl.LOCK_UN)
fmutex.close()

#child.py
import time
import subprocess
import file_lock_lib
import os
PARENT_LOCK_NAME = "ParentChildTask"
CHILD_LOCK_NAME = "ChildTask-%d"

def main():
print("CHILD PID  =================" + str(os.getpid()))
#check if parent process is running
fmutex, res = file_lock_lib.FileLock(PARENT_LOCK_NAME, True)
if res:
file_lock_lib.FileUnlock(fmutex)
print("Parent process is not running")
exit(1)
print("Child Started")
#spwan a thread to do work
#wait on Parent
mtx, res = file_lock_lib.FileLock(CHILD_LOCK_NAME%os.getpid())
file_lock_lib.FileUnlock(mtx)
print("Child Exited as parent process was killed")

if __name__ == '__main__':
main()

我想出了解决这个问题的办法。考虑上面代码中的父进程和子进程。希望这个解决方案有效。。。。

相关内容

最新更新