2014-01-16 3 views
1

У меня есть dict, который я хочу поделиться с 4 процессами, которые изменяют значения в этом dict в режиме реального времени. Файл dict создается с помощью Manager().dict() Вопрос в том, нужно ли блокировать ресурс каждый раз, когда процесс изменяет dict? Что делать, если 4 обрабатывает доступ к этому dict в режиме реального времени?доля dict между процессом

+1

тогда у вас будут условия гонки ... скорее всего ... это зависит от того, как вы его изменяете (все они меняют одни и те же ключи? Разные ключи (например, каждый процесс получает свой собственный ключ) –

ответ

3

Тогда вы увидите неопределенное поведение. Вот простой тест программы:

def worker(t): 
    d, i = t 
    d[i % 10] += 1 

if __name__ == "__main__": 
    import multiprocessing as mp 
    pool = mp.Pool() 
    d = mp.Manager().dict() 
    for i in range(10): 
     d[i] = 0 
    pool.map(worker, ((d, i) for i in xrange(1000))) 
    pool.close() 
    pool.join() 
    print d, sum(d.values()) 

А вот пример вывода из 3-х серий:

{0: 97, 1: 96, 2: 98, 3: 96, 4: 96, 5: 99, 6: 97, 7: 96, 8: 96, 9: 94} 965 
{0: 97, 1: 97, 2: 96, 3: 97, 4: 97, 5: 97, 6: 95, 7: 95, 8: 93, 9: 96} 960 
{0: 98, 1: 97, 2: 98, 3: 96, 4: 97, 5: 95, 6: 97, 7: 97, 8: 97, 9: 98} 970 

Чтобы получить «ожидаемый» отсчет 100 в каждом ведре, вам нужно создать mp.Manager().Lock() объект слишком, передать его и использовать в worker() для защиты мутации dict.

+0

Вместо того, блокировка в рабочем ящике явно может быть проще подкласса 'multiprocessing.managers.DictProxy' и wrap' _callmethod() 'в блокировке/разблокировке, а затем зарегистрировать новый тип в' SyncManager' как 'syncDict' или что-то в этом роде. я действительно удивлен, что нет фабрики или чего-то еще для создания синхронизированных управляемых объектов ... –

+0

Я согласен, это означает, что пользователи должны заботиться о блокировке каждый раз, когда хотят разделить состояние между процессом! – nam

+0

Это наверняка , но многопроцессорность работает точно так же, как и многопоточность в этом отношении, за исключением того, что гораздо более дорогостоящее разделение состояния между процессами, чем поперечные нити. Как это сделать, после добавления всего кода блокировки, по крайней мере, вы будете знать *, почему ваш многопроцессорный код работает медленнее, чем свинец с 1 ногой ;-) –

Смежные вопросы