|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 天圆突破 于 2018-7-15 00:07 编辑
- import os
- import multiprocessing
- from random import randint,choice
- from time import sleep
- def father(queue):
- lst = [choice([i for i in range(100000,999999)]) for j in range(randint(3,7))] #模拟未知的url们
- print('father start!')
- while lst:
- getData = lst.pop() #模拟爬取url的过程
- sleep(1) #requests需要时间
- queue.put(getData)
- print('father end')
-
-
- def son(queue):
- if not queue.empty():
- getData = queue.get() #模拟收到father爬到的url
- getData = str(getData) #模拟根据url爬取二级页面
- sleep(4)
- return os.getpid(), list(getData)
- return
- def record(*args): #模拟记录数据库
- if args[0] != None:
- print('record:', *args)
- def main():
- queue = multiprocessing.Manager().Queue()
- pool = multiprocessing.Pool(3)
- print('===== START =====')
-
- t = multiprocessing.Process(target=father, args=(queue,))
- t.start()
-
- print('========== WHILE ==========')
- while t.is_alive() or not queue.empty():
- pool.apply_async(func=son, args=(queue,), callback=record)
- print('========== WHILE END ==========')
- print(t.is_alive() , queue.empty())
-
- t.join()
- pool.close()
- pool.join()
- print('===== end =====')
- if __name__ == '__main__':
- main()
复制代码
上面代码是模拟了一个爬虫的过程(模拟而已),father模拟负责爬取主url的进程,son负责把father爬下来的url打开二级页面爬取二级页面的内容,record负责把son爬下来的二级页面记录(写入数据库)。father和son使用队列通信,son通过进程池实现。
我查看了很多关于进程池的博客文章,他们都是通过一个for循环来实现,但是我这个需求,因为主进程(father)不知道会爬下来多少url,所以无法用for循环,只能使用一个while循环:当主进程跑完并且队列里的数据都被处理完,进程池退出。
但是最后的结果发现,进程池里的进程跑完后并不会注销。
请问上面的代码问题出现在哪里?要想实现我想要的功能,需要怎么修改? |
|