2013-06-11 4 views
0

Я пытался узнать, как многопроцессор работает в python, и создал очень простой скрипт для проверки моего понимания.Пока цикл прерывает передачу значений переменной в процессе python

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

Если я заменю цикл while циклом for или полностью удаляю его, все будет работать так, как ожидалось.

Вот main.py:

from timepieces import Stopwatch 

def run(): 
    watch = Stopwatch() 
    watch.start() 

    can_count = 0 if (raw_input('Press q to stop and see seconds counted') == 'q') else 1 

    watch._can_count.value = can_count 

    print watch.get_seconds() 

if __name__ == "__main__": 
    run() 

И timepieces.py файл (содержит класс, который создает и управляет процессом):

from multiprocessing import Process, Value 
import time 
import math 

class Stopwatch: 
    _count_val = None 
    _proc = None 
    _can_count = None 

    def count_seconds(self, can_count, count_val): 
     seconds = 0 
     count_val.value = 23 
     #print can_count.value == 1 

     while can_count.value == 1: 
      seconds += 1 

     count_val.value = seconds 

    def start(self): 
     self._count_val = Value('i', 0) 
     self._can_count = Value('i', 1) 

     self._proc = Process(target = self.count_seconds, args = (self._can_count, self._count_val)) 
     self._proc.start() 

    def get_seconds(self): 
     return self._count_val.value 

Любые мысли приветствуются.

ответ

1

Вам необходимо присоединиться к дочернему процессу, когда вы закончите с ним. Вот более чистый пример того, чего вы пытаетесь достичь. Обратите внимание, что все материалы, связанные с процессом, инкапсулированы в один класс? Он упрощает работу с потоками и процесс, если вы можете взаимодействовать с ними через чистый интерфейс.

Вот основной модуль

from asynctimer import AsyncTimer 
import time 

def run(): 
    atimer = AsyncTimer() 

    atimer.start() 

    print 'initial count: ', atimer.get_seconds(); 

    print 'Now we wait this process,' 
    print 'While the child process keeps counting' 

    time.sleep(3) 

    print '3 seconds later:', atimer.get_seconds(); 

    atimer.stop() 

if __name__ == '__main__': 
    run() 

Вот класс, который обрабатывает дочерний процесс.

from multiprocessing import Process, Value 

class AsyncTimer(): 

    def __init__(self): 
     self._proc = None 
     self._do_count = Value('b',True) 
     self._count = Value('i', 0) 

    def _count_seconds(self): 

     while self._do_count.value: 
      self._count.value += 1 

    def start(self): 
     self._proc = Process(target=self._count_seconds) 
     self._proc.start() 

    def stop(self): 
     self._do_count.value = False 
     self._proc.join() 

    def get_seconds(self): 
     return self._count.value 
+1

Приветствия, но есть ли причина, по которой вы передаете _do_count и переменные _count в функцию, а затем просто вызываете их через ссылку на класс? Я бы предположил, что если вы используете self._do_count, вам не нужно передавать его в качестве аргумента. – achillesminor

+0

@achillesminor Хорошее место. Ответ - нет, этот бит лишний. С моей стороны это просто неуклюжесть. Я отредактировал свой ответ, чтобы удалить нарушающий код. – Steve

+0

Прохладный; снова, спасибо за своевременный ответ! – achillesminor

1

Я не уверен, если вы хотели этого или нет, но она не должна быть

while can_count.value == 1: 
    seconds -= 1 
    count_val.value = seconds 

, как вы есть, цикл никогда бы не выход, я думаю. Я все еще изучаю python, так что я не уверен на 100%.

+0

Нет, потому что если вы посмотрите на main.py, пользователю предлагается для ввода, значение проверяется и 0 или 1 значение затем передается в классы «можно считать» переменную, которая разделяется процессом, который запускается классом при запуске. Логика на всем пути ужасна, как будто вы не набираете один символ, который система ищет, _will_ переходит в бесконечный цикл; однако, я не думаю, что отсутствие проверок является тем, что вызывает проблему, с которой я сталкиваюсь. – achillesminor

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