2017-02-09 3 views
1

Для анализа веб-скрепок мне нужны две петли, которые запускаются постоянно, один возвращает список с обновляемыми веб-сайтами каждые x минут, в то время как другой анализирует сайты (старые новые) каждые y секунд. Это код конструкции, которая служит примером, что я пытаюсь сделать, но это не работает: кодекс был отредактирован, чтобы включить ответы и мои исследованияработает два взаимозависимых цикла while в python?

from multiprocessing import Process 
import time, random 

from threading import Lock 
from collections import deque 

class MyQueue(object): 
    def __init__(self): 
     self.items = deque() 
     self.lock = Lock() 

    def put(self, item): 
     with self.lock: 
      self.items.append(item) 
# Example pointed at in [this][1] answer 
    def get(self): 
     with self.lock: 
      return self.items.popleft() 

def a(queue): 
    while True: 
     x=[random.randint(0,10), random.randint(0,10), random.randint(0,10)] 
     print 'send', x 
     queue.put(x) 
     time.sleep(10) 


def b(queue): 
    try: 
     while queue: 
      x = queue.get() 
      print 'recieve', x 
      for i in x: 
       print i 
      time.sleep(2) 
    except IndexError: 
     print queue.get() 



if __name__ == '__main__': 
    q = MyQueue() 
    p1 = Process(target=a, args=(q,)) 
    p2 = Process(target=b, args=(q,)) 
    p1.start() 
    p2.start() 
    p1.join() 
    p2.join() 

Итак, это мой первый проект Python после онлайн-курс обучения, и я изо всех сил стараюсь здесь много времени. Теперь я понимаю, что функции действительно не работают параллельно, так как b не запускается до тех пор, пока не будет завершено (я использовал this, отвечая на таймер и пока True). EDIT: Даже после использования подхода, указанного в ответе, я думаю, что это все еще так, поскольку queue.get() выдает сообщение IndexError, deque пуст. Я могу только объяснить, что процесс не заканчивается, потому что когда я печатаю queue.get() сразу после .put (x), он не пуст.

В конце концов я хочу выход так:

send [3,4,6] 
3 
4 
6 
3 
4 
send [3,8,6,5] #the code above gives always 3 entries, but in my project 
3    #the length varies 
8 
6 
5 
3 
8 
6 
. 
. 

Что мне нужно для наличия двух действительно параллельных циклов, где один возвращается обновленный список каждые х минут, когда другой цикл необходим в качестве основы для анализа? Действительно ли процесс - это правильный инструмент? И где я могу получить хорошую информацию о разработке моей программы.

+1

Тема, безусловно, самый простой ответ на вашу проблему! Это может быть страшно, но это довольно легко сделать в Python. – Fabich

+0

@Lordofdark. Я возьму этот совет и прочитаю темы! Благодарю. – user2822564

ответ

2

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

https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes

Создайте очередь первый и передать его в обоих процессах. Его можно написать, а другой можно прочитать.

Одна проблема, которую я помню, заключается в том, что процесс чтения будет блокироваться в очереди до тех пор, пока что-то не будет нажата, поэтому вам может понадобиться направить специальное сообщение о завершении в очередь, когда процесс 1 будет выполнен таким образом 2 знает, что нужно остановиться.

EDIT: Простой пример. Это не включает чистый способ остановить процессы. Но он показывает, как вы можете запустить 2 новых процесса и передать данные от одного к другому. Поскольку блоки очереди на функции get() b будут автоматически ждать данных от a до продолжения.

from multiprocessing import Process, Queue 
import time, random 

def a(queue): 
    while True: 
     x=[random.randint(0,10), random.randint(0,10), random.randint(0,10)] 
     print 'send', x 
     queue.put(x) 
     time.sleep(5) 


def b(queue): 
    x = [] 
    while True: 
     time.sleep(1) 
     try: 
      x = queue.get(False) 
      print 'receive', x 
     except: 
      pass 
     for i in x: 
      print i 


if __name__ == '__main__': 
    q = Queue() 
    p1 = Process(target=a, args=(q,)) 
    p2 = Process(target=b, args=(q,)) 
    p1.start() 
    p2.start() 
    p1.join() 
    p2.join() 
+0

Спасибо за помощь, в первую очередь. Я читал в очередях и пытался играть с ним. Однако я не могу заставить ваш пример работать. Я получаю объект 'TypeError: 'Queue' is iterable'.And не является q = Queue.Queue() или что-то не хватает? Я видел это в одном примере. – user2822564

+0

Простите, я сделал несколько незначительных ошибок. Я обновил этот пример и фактически запустил код на этот раз. – trelltron

+0

это действительно хорошо! Но у меня все еще осталась одна серьезная проблема: ваш код печатает «i in x» только один раз. Цикл while перед 'for i in x' печатает его непрерывно, но не принимает новую queue.get(). Поэтому я получаю 'receive [new list]', но 'print i' все еще печатает старый список. В моей реальной жизни функция проекта 1 предоставляет изменяющийся список URL-адресов, функция 2 должна анализироваться непрерывно, будучи «восприимчивой» к новым входам в списке. Какая правильная конструкция для этого? – user2822564

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