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

Я попытался написать очень простой пример (см. Ниже), используя многопроцессорные процессы и очереди, где запускается дочерняя функция и начинается цикл. На каждой итерации он добавляет значение в очередь, чтобы его можно было передать извне. Однако значение, которое я получаю из очереди, получается из того, сколько раз я запрашивал queue.get ().

Запустите код, и проблема может иметь больше смысла. Альтернативный и более простой способ сделать это высоко ценится.

import time
from multiprocessing import Process, Queue

def f(q): 
    z = 0
    while True:
        z = z+1
        print 'z', z
        q.put(['f is at z value {}'.format(z)])
        time.sleep(float(0.1))        

if __name__ == '__main__':
    queue = Queue()
    process = Process(target=f, args=(queue,)) 
    process.start()
    print 'start with z value:'
    print queue.get()
    time.sleep(1)

    print 'now f is at z value:'
    print queue.get()

    time.sleep(1)        
    print 'terminating with z  value:'
    print queue.get()    
    process.terminate()
2
Andre 29 Авг 2017 в 18:10

4 ответа

Лучший ответ

Вы можете использовать Array или Value из multiprocessing в делят состояние между процессами:

import time
from multiprocessing import Process, Value

def f(v):
    z = 0
    while True:
        z = z+1
        print 'z', z
        v.value = z
        time.sleep(float(0.1))        

if __name__ == '__main__':
    value = Value('i')
    value.value = -1
    process = Process(target=f, args=(value,))
    process.start()
    print 'start with z value:'
    print value.value
    time.sleep(1)

    print 'now f is at z value:'
    print value.value

    time.sleep(1)        
    print 'terminating with z  value:'
    print value.value
    process.terminate()

Выход:

start with z value:
-1
z 1
z 2
z 3
z 4
z 5
z 6
z 7
z 8
z 9
z 10
now f is at z value:
10
z 11
z 12
z 13
z 14
z 15
z 16
z 17
z 18
z 19
z 20
terminating with z  value:
20
1
niemmi 29 Авг 2017 в 15:33

Класс был бы лучшей структурой для обработки запроса состояния вместо функции. Попробуй это :

class MyProcess():
  def __init__(self):
    self.state = None

  def start_process(self):
    #manage your state handling here or in an other method.
    self.state = "set state"

p = MyProcess()
queue = Queue()
process = Process(target=p.start_process, args=(queue,)) 
process.start()
print(p.state) #get the state
0
Pobe 29 Авг 2017 в 15:32

Похоже, вам нужно общее значение

import time
from multiprocessing import Process, Value

def f(z):
    while True:
        z.value += 1
        print 'z', z.value
        time.sleep(float(0.1))        

if __name__ == '__main__':
    z = Value('i', 0)

    process = Process(target=f, args=(z,)) 
    process.start()
    print 'start with z value:', z.value
    time.sleep(1)

    print 'now f is at z value:', z.value

    time.sleep(1)        
    print 'terminating with z  value:', z.value

    process.terminate()

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

1
Nick Craig-Wood 29 Авг 2017 в 15:32

Как описано в руководстве по очереди, Queue.get ( )

Удалить и вернуть элемент из очереди.

Это означает, что он получает доступ к объектам последовательно: он удаляет первый, затем второй и т. Д. Это нормальное поведение, поскольку очередь работает в режиме FIFO (сначала во-первых, а потом-в-первых).

Таким образом, при первой проверке содержимого очереди Queue.get () удаляет первый элемент в очереди. На данный момент в очереди есть только один элемент.

При второй проверке Queue.get () удаляет второй элемент в очереди. На данный момент в очереди 9 элементов (первый уже удален); но вы получаете доступ только ко второму.

В третий раз, когда вы проверяете очередь, вы удаляете третий элемент, но в очереди есть 18 элементов (вы уже удалили 1-й и 2-й элемент)

Чтобы увидеть это поведение в действии, добавьте следующую строку перед проверкой очереди:

print 'Queue size: {}'.format(queue.qsize())
print queue.get()

Проблема заключается в том, что если вы хотите проверить текущее состояние процесса, очередь не подходит для этого, поскольку она ставит в очередь сообщения, она не <. em> сообщить о текущем состоянии.

1
oldMammuth 29 Авг 2017 в 15:45
45942631