2012-05-25 5 views
1

Quelle est la meilleure façon de rendre un appel asynchrone synchrone? Par exemple, quelque chose comme ça, mais comment puis-je coordonner le thread appelant et le thread de réponse asynchrone? En java je pourrais utiliser un CountDownLatch() avec un délai d'attente, mais je ne peux pas trouver une solution définitive pour PythonRendre un appel asynchrone synchrone en Python

def getDataFromAsyncSource(): 
    asyncService.subscribe(callback=functionToCallbackTo) 
    # wait for data 
    return dataReturned 

def functionToCallbackTo(data): 
    dataReturned = data 
+0

Quelle bibliothèque utilisez-vous pour les appels asynchrones? – schlamar

+0

C'est une bibliothèque propriétaire qui s'interface avec Bloomberg. C'est pub/sub standard. – ashbyp

Répondre

5

Il y a un module, vous pouvez utiliser

import concurrent.futures 

Vérifiez ce poste pour l'échantillon code module lien de téléchargement: Concurrent Tasks Execution in Python

Vous pouvez mettre les résultats de l'exécuteur testamentaire à l'avenir, puis les obtenir, voici l'exemple de code de http://pypi.python.org:

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
    'http://www.cnn.com/', 
    'http://europe.wsj.com/', 
    'http://www.bbc.co.uk/', 
    'http://some-made-up-domain.com/'] 

def load_url(url, timeout): 
    return urllib.request.urlopen(url, timeout=timeout).read() 

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    future_to_url = dict((executor.submit(load_url, url, 60), url) 
        for url in URLS) 

    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     if future.exception() is not None: 
      print('%r generated an exception: %s' % (url,future.exception())) 
     else: 
      print('%r page is %d bytes' % (url, len(future.result()))) 
+1

Plus généralement, cela dépend de la fonctionnalité de la technologie d'exécution asynchrone qu'utilise OP. – Marcin

+0

Lien vers les documents: http://docs.python.org/dev/library/concurrent.futures.html#module-concurrent.futures – Michal

3

Une solution courante serait l'utilisation d'un Queue synchronisé et le passage à la fonction de rappel. Voir http://docs.python.org/library/queue.html.

Donc, pour votre exemple, cela pourrait ressembler (je devine juste l'API pour passer des arguments supplémentaires à la fonction de rappel):

from Queue import Queue 

def async_call(): 
    q = Queue() 
    asyncService.subscribe(callback=callback, args=(q,)) 
    data = q.get() 
    return data 

def callback(data, q): 
    q.put(data) 

C'est une solution en utilisant l'interne de sorte qu'il ne pourrait pas le module threading travailler en fonction de votre bibliothèque asynchrone.

Questions connexes