2015-05-11 2 views
2

Это очень маленький скрипт замерзает после выполнения:скрипт зависает после ввода много элементов в очереди

from multiprocessing import Queue 
q = Queue() 
for x in range(10000): 
    q.put("hello") 
print "ok" 

Он печатает «ОК» правильно, но тогда просто не заканчивается, и я должен вручную убить процесс. Я проверил вывод q.full(), и он всегда возвращает False. Если добавить второй цикл, который получает все элементы из очереди заканчивается правильно:

for x in range(10000): 
    q.get() 

Если я уменьшить число до 1000, он также заканчивается правильно. Так в чем проблема? Есть ли какой-то предел, о котором я не знаю, или я неправильно понимаю что-то фундаментальное в отношении очередей?

EDIT

То же самое происходит, если я использую трубу вместо очереди:

output_p, input_p = Pipe() 
for x in range(10000): 
    input_p.send("hello") 

ответ

1

Это не понятно, почему она не прекращается, но это дает подсказку:

close()
Указывает, что данные данные не будут помещены в очередь для текущего процесса. Фоновый поток прекратится, как только он сбросит все буферизованные данные в трубу. Это вызывается автоматически, когда очередь на сбор мусора

Это означает, что приведенный выше код создает фоновый поток для обработки очереди. Когда код заканчивается, Python пытается закрыть очередь. Обработчик очереди попытается очистить очередь, но нет получателя (Process), и поэтому он зависает.

Я бы ожидал исключения. Тем более что Ctrl + C не работает.

+0

Спасибо! Мне действительно удалось заставить его работать с помощью 'cancel_join_thread()'. Я до сих пор не знаю, почему это происходит на этом произвольном числе. – basilikum

1

мне удалось заставить его работать, используя cancel_join_thread (manual):

Предупреждение: Как уже упоминалось выше, если дочерний процесс поставил элементы на очереди (и он не используется JoinableQueue.cancel_join_thread), затем этот процесс не будет завершен до тех пор, пока все буферизованные элементы не будут , сброшенными в трубу.

Это означает, что если вы попытаетесь присоединиться к этому процессу , вы можете зайти в тупик, если не уверены, что все предметы, у которых есть , были помещены в очередь. Аналогично, если дочерний процесс не является демоническим, тогда родительский процесс может зависать при выходе, когда пытается объединить все его не-демонические дети.

Это не объясняет, почему это происходит с 10000 наименованиями, а не с 1000 наименованиями. Поэтому мне было бы любопытно узнать больше об этом, и, возможно, кто-то сможет подробнее рассказать об этом.

+0

Между процессами существует буфер 4 КБ.Может быть, 1000 предметов по-прежнему вписываются в буфер? –

+0

@AaronDigulla Хорошо, хорошо знать, но я не уверен, что это может быть так, так как пять символов будут занимать (по крайней мере) 5 байт. Таким образом, это уже должно содержать до 5000 байт, что уже больше, чем буфер. Он также по-прежнему работает с 2000 элементами (10 000 байт = 9,8 КБ). – basilikum

+0

Плюс объекты, вероятно, тоже будут мариноваться, что сделало бы их еще большими. Я думаю, кто-то должен посмотреть на код, чтобы посмотреть, что он на самом деле делает. –