鱼C论坛

 找回密码
 立即注册
查看: 624|回复: 1

关于进程池的一个问题,求高手们解答

[复制链接]
发表于 2018-7-14 23:55:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 天圆突破 于 2018-7-15 00:07 编辑

  1. import os
  2. import multiprocessing
  3. from random import randint,choice
  4. from time import sleep

  5. def father(queue):
  6.     lst = [choice([i for i in range(100000,999999)]) for j in range(randint(3,7))]      #模拟未知的url们
  7.     print('father start!')
  8.     while lst:
  9.         getData = lst.pop()                                                             #模拟爬取url的过程
  10.         sleep(1)                                                                        #requests需要时间
  11.         queue.put(getData)
  12.     print('father end')
  13.    
  14.    
  15. def son(queue):
  16.     if not queue.empty():
  17.         getData = queue.get()                                                           #模拟收到father爬到的url
  18.         getData = str(getData)                                                          #模拟根据url爬取二级页面
  19.         sleep(4)
  20.         return os.getpid(), list(getData)
  21.     return


  22. def record(*args):                                                                      #模拟记录数据库
  23.     if args[0] != None:
  24.         print('record:', *args)


  25. def main():
  26.     queue = multiprocessing.Manager().Queue()
  27.     pool = multiprocessing.Pool(3)
  28.     print('===== START =====')
  29.    
  30.     t = multiprocessing.Process(target=father, args=(queue,))
  31.     t.start()
  32.    
  33.     print('========== WHILE ==========')
  34.     while t.is_alive() or not queue.empty():
  35.         pool.apply_async(func=son, args=(queue,), callback=record)
  36.     print('========== WHILE END ==========')
  37.     print(t.is_alive() , queue.empty())
  38.    
  39.     t.join()
  40.     pool.close()
  41.     pool.join()
  42.     print('===== end =====')

  43. if __name__ == '__main__':
  44.     main()
复制代码


上面代码是模拟了一个爬虫的过程(模拟而已),father模拟负责爬取主url的进程,son负责把father爬下来的url打开二级页面爬取二级页面的内容,record负责把son爬下来的二级页面记录(写入数据库)。father和son使用队列通信,son通过进程池实现。
我查看了很多关于进程池的博客文章,他们都是通过一个for循环来实现,但是我这个需求,因为主进程(father)不知道会爬下来多少url,所以无法用for循环,只能使用一个while循环:当主进程跑完并且队列里的数据都被处理完,进程池退出。
但是最后的结果发现,进程池里的进程跑完后并不会注销。
请问上面的代码问题出现在哪里?要想实现我想要的功能,需要怎么修改?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-31 17:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表