2011-12-15 3 views
0

Недавно я хотел разработать границу HTTP-сервера для переноса моей кластерной программы ipcontroller/ipengine. Сервер является простым производным от BaseHTTPServer. Когда сервер получает запрос HTTP Get, его метод do_GET вызывает несколько методов mec.execute() для завершения задания. Вот пример кода.Проблема синхронизации в параллельных вычислениях IPython

do_GET 
{ 
b = parameter 
mec.scatter("a", b) 
mec.execute("c=fun(a)") 
d = mec.gather("c") 
write d 
} 

Я столкнулся с проблемой синхронизации в инструкции mec.execute ("c = fun (a)")? Из моего предположения, переменная «c» будет создана на каждом ipengie со значением «fun (a)». Если два потока вызовут метод do_Get одновременно с другим параметром, каково будет значение «c» на каждом из ipengine.

ответ

1

Если вы можете выразить задачу как один вызов параллельной функции, то вы должны быть безопасными, потому что никакие другие запросы не могут проникнуть между (и Глобалы двигателя не нужно трогать), например:

from IPython import parallel 

rc = parallel.Client() 
view = rc[:] 

@view.parallel(block=True) 
def pfun(a): 
    """each engine will get a chunk of a, not the whole thing""" 
    c = fun(a) 
    return c 

# a will be scattered and c will be gathered 
c = pfun(a) 

Но если нет, то самое легкое решение, вероятно, заключается в том, чтобы убедиться, что у вас нет коллизий имен между заданиями, предоставив переменным для данного запроса уникальный суффикс с UUID:

import uuid 
suffix = str(uuid.uuid4()).replace('-','') # remove '-' so we have a valid identifier 
a_name = "a_" + suffix 
c_name = "c_" + suffix 
mec.scatter(a_name, b) 
mec.execute("%s = fun(%s)" % (c_name, a_name)) 
d = mec.gather(c_name) 
Смежные вопросы