2014-08-21 2 views
0

Ive пыталась прочитать потоки и многопроцессорность, но все примеры сложны и расширены для моего уровня знаний о программировании на языке python/programming. Я хочу запустить функцию, состоящую из цикла while, и пока этот цикл выполняется, я хочу продолжить работу с программой и в конечном итоге изменить условие цикла while и завершить этот процесс. Это код:Python простейшая форма многопроцессорной обработки

class Example(): 

    def __init__(self): 
     self.condition = False 

    def func1(self): 
     self.condition = True 
     while self.condition: 
      print "Still looping" 
      time.sleep(1) 
     print "Finished loop" 

    def end_loop(self): 
     self.condition = False 

Я делаю следующие функции-вызовы:

ex = Example() 
ex.func1() 
time.sleep(5) 
ex.end_loop() 

То, что я хочу для func1, чтобы запустить в течение 5 секунд перед end_loop() вызывается и изменяет состояние и концы цикл и, следовательно, также функцию. Т.е. я хочу, чтобы один процесс запускался и «переходил» на func1и в то же время Я хочу, чтобы time.sleep(5) вызывался, поэтому процессы «раскалываются» при достижении func1, один процесс вводит функцию, а другой продолжает работу по программе и начать с выполнения time.sleep(5).

Это должен быть самый простой пример многопроцесса, все же у Ive возникли проблемы с поиском простого способа сделать это!

Спасибо

edit1: относительно do_something. В моей реальной проблеме do_something заменяется кодом, который связывается с другой программой через сокет и получает пакеты с координатами каждые 0,02 секунды и сохраняет их в membervariables класса. Я хочу, чтобы это постоянное обновление координат начиналось, а затем можно было читать координаты с помощью других функций одновременно.

Однако это не так актуально. Что делать, если do_something заменяется:

time.sleep(1) 
print "Still looping" 

Как мне решить мою проблему тогда?

EDIT2: Я попытался мультипроцессирование так:

from multiprocessing import Process 
ex = Example()  
p1 = Process(target=ex.func1()) 
p2 = Process(target=ex.end_loop()) 

p1.start() 
time.sleep(5) 
p2.start() 

Когда я побежал это, я никогда не получил p2.start(), так что не помогло. Даже если бы это было не так, как я и ищу. То, что я хочу, было бы просто начать процесс p1, а затем продолжить с time.sleep и ex.end_loop()

+0

Пожалуйста, будьте конкретны о 'do_something'. – filmor

+0

см. Отредактированный вопрос – erling

+0

Я читал, что python concurrent.futures был более простым способом обработки многопоточности по сравнению с многопроцессорной обработкой python. Однако я еще не копаю еще. Может быть, вы могли бы попробовать. –

ответ

1

Первая проблема с вашим кодом являются звонки

p1 = Process(target=ex.func1()) 
p2 = Process(target=ex.end_loop()) 

С ex.func1() вы призывающие функции и передать возвращаемое значение как target параметр. Поскольку функция ничего не возвращает, вы фактически звоните

p1 = Process(target=None) 
p2 = Process(target=None) 

который делает, конечно, никакого смысла.

После фиксации, что следующая проблема будет общие данные: при использовании multiprocessing пакета, вы реализуете параллелизм с использованием нескольких процессов, которые, по умолчанию, не может просто обмениваться данными AFAIK.Взгляните на Sharing state between processes в документации пакета, чтобы прочитать об этом. Особенно учитывайте первое предложение: «при выполнении параллельного программирования обычно лучше избегать использования общего состояния, насколько это возможно»!

Чтобы узнать о том, как отправлять и получать данные между двумя различными процессами, вы можете также взглянуть на Exchanging objects between processes. Таким образом, вместо того, чтобы просто установить флаг, чтобы остановить цикл, может быть лучше, чтобы отправить сообщение, чтобы сигнал цикла был прекращен.

Также обратите внимание, что процессы представляют собой тяжелую форму многопроцессорности, они порождают несколько процессов ОС, которые имеют относительно большие накладные расходы. multiprocessing Главная задача заключается в том, чтобы избежать проблем, наложенных Python Замок глобального перехватчика (об этом читайте далее ...) Если ваша проблема не намного сложнее, чем то, что вы нам сказали, вы можете использовать threading пакет вместо: потоки идут с меньшими затратами, чем процессы, а также позволяет получить доступ к тем же данным (хотя на самом деле следует читать о синхронизации при этом ...)

боюсь, многопроцессорная является по своей сути сложный предмет. Поэтому я думаю, вам нужно будет продвигать свои навыки программирования/питона, чтобы успешно использовать его. Но я уверен, что вы справитесь с этим, документация на python об этом будет всеобъемлющей, и об этом будет много других ресурсов.

0

Чтобы решить проблему с EDIT2, вы можете попробовать использовать карту общей памяти Value.

import time 
from multiprocessing import Process, Value 

class Example(): 

    def func1(self, cond): 
    while (cond.value == 1): 
     print('do something') 
     time.sleep(1) 
    return 

if __name__ == '__main__': 

    ex = Example() 
    cond = Value('i', 1) 
    proc = Process(target=ex.func1, args=(cond,)) 

    proc.start() 
    time.sleep(5) 
    cond.value = 0 
    proc.join() 

(Обратите внимание на target=ex.func1 без скобок и запятой после конд в args=(cond,).)

Но посмотрите на ответ, предоставленной MartinStettner, чтобы найти хорошее решение.

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