Понимание os.fork и Queue.Queue - PullRequest
6 голосов
/ 30 марта 2012

Я хотел реализовать простую программу на Python, используя параллельное выполнение.Это связано с вводом / выводом, поэтому я решил, что потоки будут уместны (в отличие от процессов).Прочитав документацию по Queue и fork, я подумал, что может сработать что-то вроде следующего:

q = Queue.Queue()

if os.fork():            # child
    while True:
        print q.get()
else:                    # parent
    [q.put(x) for x in range(10)]

Однако вызов get () никогда не возвращается.Я думал, что он вернется, как только другой поток выполнит вызов put ().При использовании модуля потоков все работает более ожидаемым образом:

q = Queue.Queue()

def consume(q):
    while True:
        print q.get()

worker = threading.Thread (target=consume, args=(q,))
worker.start()

[q.put(x) for x in range(10)]

Я просто не понимаю, почему подход с использованием форка не делает то же самое.Чего мне не хватает?

Ответы [ 3 ]

7 голосов
/ 30 марта 2012

Системный вызов POSIX fork создает новый процесс , а не новый поток внутри того же адресного пространства:

Функция fork () должна создать новый процесс.Новый процесс (дочерний процесс) должен быть точной копией вызывающего процесса (родительский процесс), за исключением случаев, описанных ниже: [...]

Таким образом, Queue дублируется в вашем первом примеревместо того, чтобы делиться между родителем и ребенком.

Вы можете использовать вместо него multiprocessing.Queue или просто использовать потоки, как во втором примере:)

Кстати,использование списочных представлений только для побочных эффектов не является хорошей практикой по нескольким причинам.Вместо этого вы должны использовать for цикл:

for x in range(10): q.put(x)
1 голос
/ 27 января 2014

Для обмена данными между несвязанными процессами вы можете использовать именованные каналы. Через функцию os.open () .. http://docs.python.org/2/library/os.html#os.open. Вы можете просто назвать канал как named_pipe = 'my_pipe' и в других программах на python использовать os.open (named_pipe,), где mode is WRONLY и так далее. После этого вы сделаете FIFO для записи в трубу. Не забудьте закрыть трубу и ловить исключения ..

0 голосов
/ 30 марта 2012

Форк создает новый процесс.Дочерний и родительский процессы не используют одну и ту же очередь: поэтому элементы, помещенные родительским процессом, не могут быть получены дочерним процессом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...