对于网页抓取分析,我需要两个永久运行的循环,一个返回列表,每隔x分钟更新一次网站,而另一个循环每隔y秒分析一次网站(旧的,新的)。这是代码构造,例如我想要做的,但它不起作用:代码已被编辑以包含答案和我的研究
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回答了一个修改计时器而且是真的)。 编辑:即使使用了答案中给出的方法,我认为情况仍然如此,因为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
.
.
我需要有两个真正的并行循环,其中一个每x分钟返回一个更新列表,另一个循环需要作为分析的基础?过程真的是正确的工具吗? 我在哪里可以获得有关设计程序的良好信息。
答案 0 :(得分:2)
我刚才做了一些这样的事情。我认为使用Process是正确的方法,但是如果你想在进程之间传递数据,那么你应该使用Queue。
https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes
首先创建队列并将其传递给两个进程。一个人可以写信给对方,另一个人可以从中读取。
我记得的一个问题是,读取进程将阻塞队列,直到某些东西被推送到队列,因此当进程1完成时,您可能需要将某种特殊的“终止”消息推送到队列中,因此进程2知道停止。
编辑:简单的例子。这不包括停止进程的干净方法。但它显示了如何启动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()