python爬虫【第2篇】【多进程】
一、多进程
1.fork方法(os模块,适用于Lunix系统)
fork方法:调用1次,返回2次。原因:操作系统经当前进程(父进程)复制出一份进程(子进程),两个进程几乎完全相同,fork方法分别在父进程、子进程中返回,子进程返回值为0,父进程中返回的是子进程的ID。
普通方法:调用1次,返回1次
import os if __name__ == '__main__':
print 'current Process (%s) start ....'%(os.getpid()) #getpid()用户获取当前进程ID
pid = os.fork()
if pid <0:
print 'error in fork'
elif pid == 0:
print 'I am child process (%s)' and my parent process is (%s)',(os.getpid(),os.getppid())
else:
print 'I (%s) created a child process (%s).',(os.getpid(),pid) 运行结果如下:
current Process (3052) start ....
I (3052) created a child process (3053).
I am child process (3053) and my parent process is (3052)
2.multiprocessing模块(跨平台)
import os # 从multiprocessing模块中导入Process类
from multiprocessing import Process def run_proc(name):
print 'Child process %s (%s) Running...' % (name,os.getpid())
if __name__ == '__main__':
print 'Parent process %s.' % os.getpid()
for i in range(5):
p = Process(target = run_proc,args = (str(i),))
print 'Process will start'
#用于启动进程
p.start()
# 用于实现进程间的同步
p.join()
print 'Process end' 执行结果如下:
Parent process 2392.
Process will start.
Process will start.
Process will start.
Process will start.
Process will start.
Child process 2 (10748) Runing...
Child process 0 (5324) Runing...
Child process 1 (3196) Runing...
Child process 3 (4680) Runing...
Child process 4 (10696) Runing...
Process end
3.multiprocessing模块(进程池)
功能:提供指定数量的进程供相互调用,默认为CPU核数。新请求提交至Pool中,若池没有满,则创建新的进程执行该请求
from multiprocessing import pool
import os,time,random def run_task(name):
print 'Task %s (pid = %s) is running...' %(name,os.getpid())
time.sleep(random.random() * )
print 'Task %s end' %name if __name__=='__main__':
print 'Current process %s' %os.getpid()
p = Pool(processs = )
for i in range():
p.apply_async(run_task,args = (i,))
print 'Waiting for all subprocesses done...'
p.close()
p.join()
print 'All subprocesses done' 执行结果:
Current process
Waiting for all subprocesses done...
Task (pid = ) is running...
Task (pid = ) is running...
Task (pid = ) is running...
Task end
Task (pid = ) is running...
Task end
Task (pid = ) is running...
Task end
Task end
Task end
All subprocesses done 常见容量为3的进程池,依次向进程池中添加5个任务。
Pool对象调用join()方法会等待所有子进程执行完毕
调用join()前须调用close()方法
调用close()方法后就不能继续添加新的Process
4.进程间通信
①.Queue:可在多个进程间的数据传递(Put和Get两种方法)
Put方法:插入数据到队列中(blocked,timeoutl两个可选参数,如果blocked为True(默认值)
并且timeout为正值,
该方法会阻塞timeout指定时间,直至队列有剩余空间,如果超时,会抛出Queue.Full异常,
如果blocked为False,但Queue已满,会立即抛出Queue.Full异常)
Get方法:
从队列读取并删除一个元素(blcoked,timeout两个可选参数,如果blocked为True(默认值)并且timeout为正值
name在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,则分为两种情况:
如果Queue有一个值可用,则立即返回该值;
否则如果队列为空,则立即抛出Queue.Empty异常
from multiprocessing import Process,Queue
import os,time,random # 写数据进程执行的代码
def proc_write(q,urls):
print ('Process (%s) is writing...' % os.getpid())
for url in urls:
q.put(url)
print('Put %s to queue...' % url)
time.sleep(random.random() * 3) # 读数据进程执行的带啊
def proc_read(q):
print ('Process (%s) is reading...' % os.getpid())
while True:
url = q.get(True)
print('Get %s from queue' % url) if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程
q = Queue()
proc_writer1 = Process(target=proc_write,args=(q,['url1','url2','url3']))
proc_writer2 = Process(target=proc_write,args=(q,['url4','url5','url6']))
proc_reader = Process(target=proc_read,args=(q,)) # 启动子进程proc_writer,写入:
proc_writer1.start()
proc_writer2.start() # 启动子进程proc_reader,读取:
proc_reader.start() # 等待proc_writer结束:
proc_writer1.join()
proc_writer2.join() #proc_reader进程是死循环,无法等待其结束,只能强行终止:
proc_reader.terminate() 执行结果:
Process(9968) is writing...
Process(9512) is writing...
Put url1 to queue...
Put url4 to queue...
Process(1124) is reading...
Get url1 from queue
Get url4 from queue Put url5 to queue...
Get url5 from queue Put url2 to queue...
Get url2 from queue Put url6 to queue...
Get url6 from queue Put url3 to queue...
Get url3 from queue
②.Pipe:用来在两个进程间进行通信,两个进程分别位于管道两端
Pipe方法返回(conn1,conn2)代表一个管道的两个端
pipe方法有duplex参数,
默认值为True,则该管道是全双工模式,即conn1、conn2均可收发
duplex为False,则conn1只负责接收消息,conn2只负责发送消息
send方法:发送消息方法
recv方法:接收消息方法
全双工模式:调用conn1.send()方法发送消息,conn1.recv接收消息,若无消息可接收,recv方法会一直阻塞;若管道已被关闭,recv方法会报错
import multiprocessing
import random
import os,random def proc_send(pipe,urls):
for url in urls:
print 'Process (%s) send: %s' %(os.getpid(),url)
pipe.send(url)
time.sleep(random.random()) def proc_recv(pipe):
while True:
print 'Process (%s) rev:%s' %(os.getpid(),pipe.recv())
time.sleep(random.random()) if __name__=='__main__':
pipe = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10)]))
p2 = multiprocessing.Process(target=proc_recv,args=(pipe[1],))
p1.start()
p2.start()
p1.join()
p2.join() 执行结果:
Process(10448) send:url_0
Process(5832) rev:url_0 Process(10448) send:url_1
Process(5832) rev:url_1 Process(10448) send:url_2
Process(5832) rev:url_2 Process(10448) send:url_3
Process(5832) rev:url_3 Process(10448) send:url_4
Process(5832) rev:url_4 Process(10448) send:url_5
Process(5832) rev:url_5 Process(10448) send:url_6
Process(5832) rev:url_6 Process(10448) send:url_7
Process(5832) rev:url_7 Process(10448) send:url_8
Process(5832) rev:url_8 Process(10448) send:url_9
Process(5832) rev:url_9
python爬虫【第2篇】【多进程】的更多相关文章
- python爬虫之多线程、多进程+代码示例
python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...
- python爬虫入门八:多进程/多线程
什么是多线程/多进程 引用虫师的解释: 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期. 进程(有时被称为重量级进程)是 ...
- Python爬虫笔记安装篇
目录 爬虫三步 请求库 Requests:阻塞式请求库 Requests是什么 Requests安装 selenium:浏览器自动化测试 selenium安装 PhantomJS:隐藏浏览器窗口 Ph ...
- python爬虫之多线程、多进程、GIL锁
背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...
- Python爬虫番外篇之Cookie和Session
关于cookie和session估计很多程序员面试的时候都会被问到,这两个概念在写web以及爬虫中都会涉及,并且两者可能很多人直接回答也不好说的特别清楚,所以整理这样一篇文章,也帮助自己加深理解 什么 ...
- Python爬虫进阶六之多进程的用法
前言 在上一节中介绍了thread多线程库.python中的多线程其实并不是真正的多线程,并不能做到充分利用多核CPU资源. 如果想要充分利用,在python中大部分情况需要使用多进程,那么这个包就叫 ...
- python爬虫番外篇(一)进程,线程的初步了解
一.进程 程序并不能单独和运行只有将程序装载到内存中,系统为他分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别在于:程序是指令的集合,它是进程的静态描述文本:进程是程序的一次执行活动, ...
- Python爬虫番外篇之关于登录
常见的登录方式有以下两种: 查看登录页面,csrf,cookie;授权:cookie 直接发送post请求,获取cookie 上面只是简单的描述,下面是详细的针对两种登录方式的时候爬虫的处理方法 第一 ...
- Python爬虫【实战篇】scrapy 框架爬取某招聘网存入mongodb
创建项目 scrapy startproject zhaoping 创建爬虫 cd zhaoping scrapy genspider hr zhaopingwang.com 目录结构 items.p ...
- Python爬虫【实战篇】百度翻译
先看代码 import requests headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS ...
随机推荐
- cuda输出
cuda的输出就是printf 可以在屏幕上显示出来,但你修改之后一定要make编译,不然只是修改了源代码,但生成的可执行文件还是之前编译的
- 51nod 1175 区间第k大 整体二分
题意: 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 分析: 仅仅就是一道整体二分的入门题而已,没听说过整体二分? 其实就是一个分治的函数 ...
- Python之爬虫-酷6视频
Python之爬虫-酷6视频 #!/usr/bin/env python # -*- coding:utf-8 -*- import re import requests response = req ...
- linux下mysql的安装与使用
一.mysql的安装 之前搭建linux下项目的发布,最后遗留的问题时数据库的迁移,如何从windows上迁移到linux上?这里首先进行mysql数据库的安装 1.下载mysql安装包 在这里下载的 ...
- String字符串类的获取功能
StringDemo.java /* * String类的获取功能: * int length():获取字符串的长度,其实也就是字符个数 * char charAt(int index):获取指定索引 ...
- PS学习笔记(05)
PS学习笔记(09) [2]马赛克背景 找一张图片.然后新建图层,让前景色背景色恢复到默认的状态(黑.白) 在新建图层上填充黑色-->滤镜-->渲染->云彩 像素化-->马赛克 ...
- Leetcode 172.阶乘后的零
阶乘后的零 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例 1: 输入: 3 输出: 0 解释: 3! = 6, 尾数中没有零. 示例 2: 输入: 5 输出: 1 解释: 5! = 120 ...
- 安装K/3 Cloud过程中发现的两个新问题。
卸载掉K/3 Cloud然后重装时出现下面的错误提示: 可能原因: 1.安装目录下的Setup.exe会检查操作系统版本.有些操作系统可能是被串改过注册信息,所以取不到版本信息(有些是因为盗版的原因) ...
- 【NOIP2017练习】怎样学习哲学(计数,DP)
题意:OI大师抖儿在夺得银牌之后,顺利保送pku.这一天,抖儿问长者:“虽然我已经保送了,但是我还要参加学考.马上就要考政治了,请问应该怎样学习哲学,通过政治考试?” 长者回答:“你啊,Too Yo ...
- 安装最新版本的zabbix
1. 先安装php5.4 最新版本: yum安装php5.4或5.5 https://blog.csdn.net/MarkBoo/article/details/49424183 2. 然后参照官网或 ...