Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从多处理脚本中干净地退出?_Python_Real Time_Multiprocessing_Nonblocking - Fatal编程技术网

Python 如何从多处理脚本中干净地退出?

Python 如何从多处理脚本中干净地退出?,python,real-time,multiprocessing,nonblocking,Python,Real Time,Multiprocessing,Nonblocking,我正在为我的网站构建一个非阻塞聊天应用程序,我决定实现一些多处理来处理数据库查询和实时消息传递 我假设当一个用户登陆到一个给定的URL以查看他们与另一个人的对话时,我将启动脚本,多处理将开始,消息将被添加到队列并显示在页面上,新消息将被发送到一个单独的队列,该队列与数据库交互,等等(常规消息功能随后出现) 但是,当用户离开此页面时会发生什么情况?我假设我需要退出这些不同的流程,但目前,这并不适合“干净”的退出。我必须终止进程,根据多进程文档: Warning: If this method (t

我正在为我的网站构建一个非阻塞聊天应用程序,我决定实现一些多处理来处理数据库查询和实时消息传递

我假设当一个用户登陆到一个给定的URL以查看他们与另一个人的对话时,我将启动脚本,多处理将开始,消息将被添加到队列并显示在页面上,新消息将被发送到一个单独的队列,该队列与数据库交互,等等(常规消息功能随后出现)

但是,当用户离开此页面时会发生什么情况?我假设我需要退出这些不同的流程,但目前,这并不适合“干净”的退出。我必须终止进程,根据多进程文档:

Warning: If this method (terminate()) is used when the associated process is using a pipe 
or queue then the pipe or queue is liable to become corrupted and may become 
unusable by other process.Similarly, if the process has acquired a lock or 
semaphore etc. then terminating it is liable to cause other processes to 
deadlock.
我还研究了
sys.exit()
;但是,如果不在各种进程上使用
terminate()
,它将无法完全退出脚本

这是我的代码,为了解决这个问题,它被简化了。如果我需要改变它,那完全可以。我只是想确保我能恰当地处理这件事

import multiprocessing
import Queue
import time
import sys

## Get all past messages
def batch_messages():   

    # The messages list here will be attained via a db query
    messages = [">> This is the message.", ">> Hello, how are you doing today?", ">> Really good!"]
    for m in messages:
        print m

## Add messages to the DB   
def add_messages(q2):   

    while True:
        # Retrieve from the queue
        message_to_db = q2.get()

        # For testing purposes only; perfrom another DB query to add the message to the DB
        print message_to_db, "(Add to DB)"

## Recieve new, inputted messages.
def receive_new_message(q1, q2):

    while True:
        # Add the new message to the queue:
        new_message = q1.get()

        # Print the message to the (other user's) screen
        print ">>", new_message

        # Add the q1 message to q2 for databse manipulation
        q2.put(new_message)

def shutdown():
    print "Shutdown initiated"
    p_rec.terminate()
    p_batch.terminate()
    p_add.terminate()
    sys.exit()

if __name__ == "__main__":

    # Set up the queue
    q1 = multiprocessing.Queue()
    q2 = multiprocessing.Queue()

    # Set up the processes
    p_batch = multiprocessing.Process(target=batch_messages)
    p_add = multiprocessing.Process(target=add_messages, args=(q2,))
    p_rec = multiprocessing.Process(target=receive_new_message, args=(q1, q2,))

    # Start the processes   
    p_batch.start() # Perfrom batch get 
    p_rec.start()
    p_add.start()

    time.sleep(0.1) # Test: Sleep to allow proper formatting

    while True:

        # Enter a new message
        input_message = raw_input("Type a message: ")

        # TEST PURPOSES ONLY: shutdown
        if input_message == "shutdown_now":
            shutdown()

        # Add the new message to the queue:
        q1.put(input_message)

        # Let the processes catch up before printing "Type a message: " again. (Shell purposes only)
        time.sleep(0.1)
我应该如何处理这种情况?我的代码需要从根本上进行修改吗?如果需要,我应该做些什么来修复它

感谢您的任何想法、评论、修订或资源

谢谢大家!

免责声明:我实际上不懂python。但是多线程的概念在所有语言中都非常相似,我知道我有足够的信心尝试回答这个问题

当使用多个线程/进程时,每个线程/进程都应该在其循环中有一个步骤来检查一个变量(我通常称该变量为“active”或“keepGoing”之类的,它通常是一个布尔值)

该变量通常在线程之间共享,或者作为消息发送给每个线程,具体取决于您的编程语言以及您希望进程停止的时间(是否先完成工作?)

设置变量后,所有线程退出其处理循环并继续退出其线程


在您的例子中,有一个循环“while true”。这永远不会存在。设置变量时将其更改为exit,当到达函数exit时,线程应自行关闭。

N.B:您不需要在标题前加上“python-”,这就是StackOverflow的标记的用途。有效点现在已修复。因此,为什么您不能执行干净的退出?关闭时,将消息传递给每个子进程,使其停止正在执行的任何操作并退出。你可能需要一个单独的线程(在每个子进程上)。哦,顺便问一下:你不能用线程代替进程吗?更安全,更容易维护。终端有什么问题?我想它应该很好用。谢谢你在这件事上的意见。我一定会考出来的。