2

私は自分のWebサイト用にノンブロッキングチャットアプリケーションを構築しており、DBクエリとリアルタイムメッセージングを処理するためにいくつかのマルチプロセッシングを実装することにしました。

ユーザーが特定のURLにアクセスして他の人との会話を確認すると、スクリプトが起動され、マルチプロセッシングが開始され、メッセージがキューに追加されてページに表示され、新しいメッセージが表示されると思います。 DBなどと対話する別のキューに送信されます(通常のメッセージ機能が続きます)。

ただし、ユーザーがこのページを離れるとどうなりますか?これらのさまざまなプロセスを終了する必要があると思いますが、現在、これは「クリーンな」終了には役立ちません。マルチプロセッシングのドキュメントによると、プロセスを終了する必要があります。

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)

この状況にどのように対処すればよいですか?コードを根本的に改訂する必要がありますか?もしそうなら、それを修正するにはどうすればよいですか?

考え、コメント、改訂、またはリソースをいただければ幸いです。

ありがとうございました!

4

1 に答える 1

2

免責事項:私は実際にPythonを知りません。しかし、マルチスレッドの概念は、私が知っているすべての言語で十分に類似しており、とにかく答えようとするのに十分な自信を持っています。

複数のスレッド/プロセスを使用する場合、それぞれが変数をチェックするためのループ内のステップを持っている必要があります(私はしばしば変数を「アクティブ」または「keepGoing」などと呼び、通常はブール値です)。

その変数は通常、プログラミング言語に応じて、スレッド間で共有されるか、メッセージとして各スレッドに送信されます。また、処理を停止するタイミングも異なります(最初に作業を終了しますか?)

変数が設定されると、すべてのスレッドは処理ループを終了し、スレッドの終了に進みます。

あなたの場合、「trueの間」のループがあります。これは決して終了しません。変数が設定されたときに終了するように変更し、関数の終了に達したときにスレッドが自動的に閉じる必要があります。

于 2013-04-03T23:12:56.027 に答える