Python多线程爬虫结束不了子进程问题解决
对于python多线程爬虫,使用multiprocessing
能有效的帮我们实现多线程的任务,如以下代码所示,这段代码看似没有什么毛病,但真正执行起来时,有时程序能正常的退出,但大多数情况下是不能正常的退出,程序一直处于阻塞的状态
def Producer(in_q,url,type): response = http.request('GET', url, headers=header) result = response.data.decode('UTF-8') jsonData = json.loads(result) print('%s---%s'%(type,jsonData["data"]["total"])) for item in jsonData["data"]: item['f0']=type item['f-1']=0 in_q.put(item) return
def Consumer(in_q): item=None try: while in_q.empty() is not True: item=in_q.get() Handle_Stock(item) in_q.task_done() return except Exception as e: print(e) #补偿重试1次 if item['f-1']==0: item['f-1']=1 in_q.put(item) in_q.task_done() return def Handle(item): if not isExist: mysql.insert() else: mysql.update() def Multithreading_Get(): start=time.time() pool=multiprocessing.Pool(16) queue=multiprocessing.Manager().Queue() params=[{'type':1,'param':'m:1+t:2'},{'type':2,'param':'m:0+t:6'},{'type':3,'param':'m:1+t:23'},{'type':4,'param':'m:0+t:80'}] for item in params: url='localhost://fields=f38,f39,f12,f14' Producer(queue,url,item['type']) print('QueueSize: %s'%queue.qsize()) for i in range(100): pool.apply_async(Consumer,args=(queue,)) print('主线程over') pool.close() #阻止后续任务提交到进程池,当所有任务执行完成后,工作进程会退出 pool.join() #等待工作进程结束。调用join前,必须close queue.join() end=time.time() print('总耗时:%s'%(end-start))
问题是出在Consumer()这个方法里,这个方法主要是消费,in_q.get()是从队列里取出对应数据
通过文档可以看出这个方法默认是开启阻塞的,当多个线程同时进入Consumer这个方法里时,都去进行get()这个操作时,必然有线程不会执行成功,而是一直阻塞在这里,所以程序就一直不能结束了
解决方案
如文档所示,get()可以对其设置一个超时时间或者关闭默认的阻塞模式