Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Israel Brewster Newsgroups: comp.lang.python Subject: Re: Bi-directional sub-process communication Date: Mon, 23 Nov 2015 12:22:33 -0900 Lines: 81 Message-ID: References: Mime-Version: 1.0 (Mac OS X Mail 9.1 \(3096.5\)) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Trace: news.uni-berlin.de VqQERBaNHvkOZAimO20c9QTXPeolKnG6DuVEb3kL62Vw== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.003 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'one?': 0.05; 'subject:skip:c 10': 0.07; 'cc:addr:python-list': 0.09; '(actually': 0.09; 'any)': 0.09; 'concern:': 0.09; 'subject:process': 0.09; 'thread': 0.10; ':-)': 0.12; 'def': 0.13; 'acquired': 0.15; '10:54': 0.16; '23,': 0.16; 'cc:name:python': 0.16; 'concurrency,': 0.16; 'order?': 0.16; 'reads,': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'responses.': 0.16; 'subject:sub': 0.16; 'threads': 0.16; 'true:': 0.16; 'wake': 0.16; 'wrote:': 0.16; 'say,': 0.18; '>>>': 0.20; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'prevent': 0.20; 'trying': 0.22; 'am,': 0.23; 'seems': 0.23; 'this:': 0.23; 'header :In-Reply-To:1': 0.24; 'mon,': 0.24; 'requests': 0.25; "i've": 0.25; 'figure': 0.27; 'order.': 0.27; 'possibility': 0.27; 'correct': 0.28; 'fine': 0.28; 'directly,': 0.29; 'locks': 0.29; 'queue': 0.29; 'objects': 0.29; 'raise': 0.29; 'url:mailman': 0.30; 'probably': 0.31; 'post': 0.31; 'another': 0.32; 'posting': 0.32; 'class': 0.33; 'url:python': 0.33; 'lock': 0.33; "i'll": 0.33; 'url:listinfo': 0.34; 'worked': 0.34; 'handle': 0.34; 'that,': 0.34; 'so,': 0.35; 'next': 0.35; 'could': 0.35; 'nov': 0.35; 'something': 0.35; 'but': 0.36; 'should': 0.36; 'instead': 0.36; 'there': 0.36; 'url:org': 0.36; 'possible': 0.36; 'child': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'received:10': 0.37; 'two': 0.37; 'thanks': 0.37; 'charset:us-ascii': 0.37; 'wrong': 0.38; 'shared': 0.38; 'enough': 0.39; 'subject:-': 0.39; 'rather': 0.39; 'url:mail': 0.40; 'called': 0.40; 'waiting': 0.60; 'care': 0.60; 'hope': 0.61; 'header:Message-Id:1': 0.61; 'identify': 0.61; 'notified': 0.62; 'side': 0.62; 'per': 0.62; 'skip:n 10': 0.62; 'complete': 0.63; 'request.': 0.66; 'received:10.9': 0.66; 'note:': 0.66; 'guaranteed': 0.67; 'therefore': 0.67; 'sole': 0.76; 'received:12': 0.81; 'responses': 0.93 X-Warning: RFC compliance checks disabled due to whitelist X-Warning: Reverse-Path DNS check skipped due to whitelist X-Warning: Maximum message size check skipped due to whitelist X-Warning: Realtime Block Lists skipped due to whitelist X-Warning: System filters skipped due to whitelist X-Warning: Domain filters skipped due to whitelist X-Warning: User filters skipped due to whitelist X-Warning: Anti-Spam check skipped due to whitelist X-Whitelist: 2147483645 X-Envelope-From: israel@ravnalaska.net X-Envelope-To: ian.g.kelly@gmail.com In-Reply-To: X-Mailer: Apple Mail (2.3096.5) X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:99283 On Nov 23, 2015, at 11:51 AM, Ian Kelly wrote: >=20 > On Mon, Nov 23, 2015 at 12:55 PM, Ian Kelly = wrote: >> On Mon, Nov 23, 2015 at 10:54 AM, Israel Brewster = wrote: >>> Concern: Since the master process is multi-threaded, it seems likely = enough that multiple threads on the master side would make requests at = the same time. I understand that the Queue class has locks that make = this fine (one thread will complete posting the message before the next = is allowed to start), and since the child process only has a single = thread processing messages from the queue, it should process them in = order and post the responses (if any) to the master_queue in order. But = now I have multiple master processes all trying to read master_queue at = the same time. Again, the locks will take care of this and prevent any = overlapping reads, but am I guaranteed that the threads will obtain the = lock and therefore read the responses in the right order? Or is there a = possibility that, say, thread three will get the response that should = have been for thread one? Is this something I need to take into = consideration, and if so, how? >>=20 >> Yes, if multiple master threads are waiting on the queue, it's >> possible that a master thread could get a response that was not >> intended for it. As far as I know there's no guarantee that the >> waiting threads will be woken up in the order that they called get(), >> but even if there are, consider this case: >>=20 >> Thread A enqueues a request. >> Thread B preempts A and enqueues a request. >> Thread B calls get on the response queue. >> Thread A calls get on the response queue. >> The response from A's request arrives and is given to B. >>=20 >> Instead of having the master threads pull objects off the response >> queue directly, you might create another thread whose sole purpose is >> to handle the response queue. That could look like this: >>=20 >>=20 >> request_condition =3D threading.Condition() >> response_global =3D None >>=20 >> def master_thread(): >> global response_global >> with request_condition: >> request_queue.put(request) >> request_condition.wait() >> # Note: the Condition should remain acquired until >> response_global is reset. >> response =3D response_global >> response_global =3D None >> if wrong_response(response): >> raise RuntimeError("got a response for the wrong request") >> handle_response(response) >>=20 >> def response_thread(): >> global response_global >> while True: >> response =3D response_queue.get() >> with request_condition: >> response_global =3D response >> request_condition.notify() >=20 > Actually I realized that this fails because if two threads get > notified at about the same time, they could reacquire the Condition in > the wrong order and so get the wrong responses. >=20 > Concurrency, ugh. >=20 > It's probably better just to have a Condition/Event per thread and > have the response thread identify the correct one to notify, rather > than just notify a single shared Condition and hope the threads wake > up in the right order. Tell me about it :-) I've actually never worked with conditions or = notifications (actually even this bi-drectional type of communication is = new to me), so I'll have to look into that and figure it out. Thanks for = the information! > --=20 > https://mail.python.org/mailman/listinfo/python-list