Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Ian Kelly Newsgroups: comp.lang.python Subject: Re: Bi-directional sub-process communication Date: Mon, 23 Nov 2015 13:51:51 -0700 Lines: 68 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: news.uni-berlin.de SMmKcNYgXWWOhjEqVSv3yQV8y5GxrZqGE9SV3NQ3NGCw== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.004 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'received:209.85.223': 0.03; 'one?': 0.05; 'subject:skip:c 10': 0.07; 'any)': 0.09; 'concern:': 0.09; 'subject:process': 0.09; 'thread': 0.10; 'def': 0.13; 'acquired': 0.15; '10:54': 0.16; '23,': 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; '2015': 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; 'order.': 0.27; 'possibility': 0.27; 'message-id:@mail.gmail.com': 0.27; 'correct': 0.28; 'fine': 0.28; 'directly,': 0.29; 'locks': 0.29; 'queue': 0.29; 'objects': 0.29; 'raise': 0.29; 'probably': 0.31; 'post': 0.31; 'another': 0.32; 'posting': 0.32; 'class': 0.33; 'lock': 0.33; 'handle': 0.34; 'that,': 0.34; 'received:google.com': 0.35; '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; 'received:209.85': 0.36; 'possible': 0.36; 'child': 0.36; 'to:addr:python-list': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'two': 0.37; 'received:209': 0.38; 'wrong': 0.38; 'shared': 0.38; 'enough': 0.39; 'subject:-': 0.39; 'rather': 0.39; 'to:addr:python.org': 0.40; 'called': 0.40; 'waiting': 0.60; 'care': 0.60; 'hope': 0.61; 'identify': 0.61; 'notified': 0.62; 'side': 0.62; 'per': 0.62; 'complete': 0.63; 'request.': 0.66; 'note:': 0.66; 'guaranteed': 0.67; 'therefore': 0.67; 'sole': 0.76; 'to:name:python': 0.84; 'responses': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:content-transfer-encoding; bh=I7M6lnhxvjgqKHCm1/rmS+dh+6j/7rRPqag+2penypI=; b=ad8hryqyAYCUIwRUAVFZFgePgdenzIUW2iPWuQy4GW3asLzNs6aURF2H2Oj/A+XehF 0kije5o0yZYTdcwRk41ycrpSeMOjCnJ6IX81AbdGln6xAJBRO7dkVZ6Zmu80LskaMCiC tpE1d85YD0ISCK9Sp2iWu57z/WKm7mVfM86gqWTHXhsASzd8e9w3k+e6Pk95Hxc3+/QA K4rgof986ZTFj220OBHKgK8wRCd3vaGbtU3xxL49dqeenb6PjzJU+cyUgcCxRzxN8QoU PQKQXfOxL28eMrALCdxWP2Ov0eGeQMFV3CfTUE9dgz6EpTT99LCQfhKbQ22HlbeFVWOs Wo6A== X-Received: by 10.107.164.154 with SMTP id d26mr27406420ioj.111.1448311950814; Mon, 23 Nov 2015 12:52:30 -0800 (PST) In-Reply-To: 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:99281 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 eno= ugh that multiple threads on the master side would make requests at the sam= e time. I understand that the Queue class has locks that make this fine (on= e thread will complete posting the message before the next is allowed to st= art), and since the child process only has a single thread processing messa= ges 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 proce= sses all trying to read master_queue at the same time. Again, the locks wil= l 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 t= he 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? > > 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: > > 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. > > 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: > > > request_condition =3D threading.Condition() > response_global =3D None > > 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) > > def response_thread(): > global response_global > while True: > response =3D response_queue.get() > with request_condition: > response_global =3D response > request_condition.notify() 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. Concurrency, ugh. 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.