如何防止进程在KeyboardInterrupt时终止?

2 投票
1 回答
824 浏览
提问于 2025-04-16 22:47

我最近在搞一个Django项目。我想实现的是,当Django项目启动在一个新的进程中时,父进程可以执行我写的一些代码(也就是我项目的后端)。显然,Django进程和父进程之间需要进行通信。我希望这两个进程能够读写一个字典。

我有以下代码,是根据这里的例子写的:

#!/usr/bin/env python

from multiprocessing import Process, Manager
import os
import time
from dj import manage

def django(d, l):
    print "starting django"

    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()
    manage.start()

def stop(d, l):

    print "stopping"
    print d
    print l

if (__name__ == '__main__'):
    os.system('clear')
    print "starting backend..."
    time.sleep(1)
    print "backend start complete."

    manager = Manager()

    d = manager.dict()
    l = manager.list(range(10))

    p = Process(target=django, args=(d, l))
    p.start()

    try:
        p.join()
    except KeyboardInterrupt:
        print "interrupt detected"

    stop(d, l)

当我按下CTRL+C来结束Django进程时,我看到Django服务器关闭,并且调用了stop()。然后我希望能看到字典d和列表l被打印出来。

输出是:

starting backend...
backend start complete.
starting django
Validating models...

0 errors found
Django version 1.3, using settings 'dj.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
^Cinterrupt detected
stopping
<DictProxy object, typeid 'dict' at 0x141ae10; '__str__()' failed>
<ListProxy object, typeid 'list' at 0x1425090; '__str__()' failed>

在按下CTRL+C后,它找不到字典或列表。那时候Manager进程是不是已经被终止了?如果是的话,有没有办法让它不在那时终止,而是和主进程一起终止呢?

希望这样说能让你明白。任何帮助都非常感谢。

1 个回答

-1

好的,按照我的理解,没有简单的方法可以忽略异常。当你抛出一个异常时,如果有“except”块,就会直接进入那个块。我这里提议的是一种方法,可以在每次按下^C(通常是中断程序的快捷键)时重启你的Django应用,但要注意,应该留一个退出的方式。

理论上,你可以用一个 try..except.. 块把每一行代码包裹起来,这样每一行就像是重启了一样,但不会像重启整个脚本那样明显。如果有人找到一个真正有效的解决方案,我会第一个给他点赞。

你可以把所有代码放在 if (__name__ == '__main__'): 里面,放到一个 main 函数里,然后留下一些像这样的代码:

def main():
    #all the code...

if (__name__ == '__main__'):
    while True:
        try:
            main()
        except KeyboardInterrupt:
            pass

撰写回答