queue 模块
方法:
1、Queue.qsize():返回队列的大致大小。
注意,size() > 0 ,不保证后续的 get() 不会阻塞;
qsize() < maxsize,也不保证 put() 不会阻塞。
2、Queue.empty():队列是否为空,是返回True否返回False。
如果empty()返回True,则不保证对put()的后续调用不会阻塞。
类似地,如果empty()返回False,则不保证对get()的后续调用不会阻塞。
3、Queue.full():队列是否已满。
4、Queue.put(item, block=True, timeout=None):将 item 放入队列。
如果可选的block为true且timeout为None(默认值),则在必要时阻塞,直到有空闲插 槽可用。
如果timeout是一个正数,它会阻止最多超时秒,如果在该时间内没有可用的空闲槽,则 会引发Full异常。
若 block 为 false,如果空闲插槽立即可用,则将项目放在队列上,否则引发完全异(在这种情况下忽略超时)。
5、Queue.put_nowait(item):相当于 put(item, False)。
6、Queue.get(block=True, timeout=None):从队列中删除并返回一个item。
如果可选的block为true且timeout为None(默认值),则在必要时阻止,直到某个项可用为止。
如果timeout是一个正数,它会阻止最多超时秒,如果在该时间内没有可用的项,则会引发Empty异常。
若 block 为 false,如果一个项立即可用则返回一个项,否则引发Empty异常(在这种情况下忽略超时)。
7、Queue.get_nowai():相当于get(False)。
8、Queue.task_done():表示以前排队的任务已完成。
由队列使用者线程使用。
对于用于获取任务的每个get(),对task_done()的后续调用会告知队列该任务的处理已完成。
9、Queue.join():主线程等待子线程结束才结束。
异常
1、Empty
在对空的Queue对象调用非阻塞 get()(或 get_nowait() )时引发异常。
queue.Empty
2、Full
在已满的Queue对象调用非阻塞 get()(或 get_nowait())时引发异常。
queue.Full
代码
1、multiprocessing
import multiprocessing
import os
def info(title):
print(title)
print(__name__)
print('father', os.getppid())
print('self', os.getpid())
print('--------')
if __name__ == "__main__": # 除了创建的子进程和子进程调用函数,其他的都是脚本主进程
# info('hello')
# 创建一个子进程调用函数
P = multiprocessing.Process(target=info,args=('hello python',))
P.start()
P.join() # 和多线程一样,也是等待的意思
print('hello word') # 若没有join则会独立运行
#运行结果:
hello python
__mp_main__
father 7808
self 7828
--------
hello word
2、join
import multiprocessing
import os
import time
def info(title):
print(title)
time.sleep(2)
print(__name__)
print('father', os.getppid())
print('self', os.getpid())
print('--------')
if __name__ == "__main__":
p1 = multiprocessing.Process(target=info,args=('A1',))
p2 = multiprocessing.Process(target=info, args=('A2',))
p3 = multiprocessing.Process(target=info, args=('A3',))
#轮流执行
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
# 这里的join只是为了卡住主进程,使得三个进程都执行完毕再执行print
# 这里很重要,以后多进程扫描文件需要完全等待几个进程全部执行完毕在汇总
print('all over')
#运行结果:
A1
A2
A3
__mp_main__
__mp_main__
father 7944
self 7192
--------
father 7944
__mp_main__
self 5516
--------
father 7944
self 3576
--------
all over
3、Rlock
# 进程同步
import os
import multiprocessing
import time
# 多进程,并发,可能乱序并发执行(主要看系统如何处理)
# 多进程加锁,挨个执行,也可能是乱序
def showdata(lock, i):
with lock:
print(multiprocessing.current_process().name)
time.sleep(2)
print(i)
if __name__ == "__main__":
lock = multiprocessing.RLock() # 创建锁
for num in range(10):
multiprocessing.Process(target=showdata, args=(lock, num)).start()
#运行结果:
Process-2
1
Process-1
0
Process-10
9
Process-6
5
Process-3
2
Process-7
6
Process-8
7
Process-4
3
Process-9
8
Process-5
4
4、pipe
# 进程通信
import multiprocessing
import os
def func(conn): # conn表示管道类型
print('func',os.getpid(), conn.recv()) # 收到的数据
conn.send(['a', 'b', 'c', 'd', 'e']) # 发送的数据
conn.close() # 关闭
if __name__ == "__main__":
conn_a, conn_b = multiprocessing.Pipe() # 创建一个管道,有两个口
# 相当于在进程中conn_a.send(['a','b','c','d','e']),发送给conn_b
p = multiprocessing.Process(target=func, args=(conn_a,)).start()
conn_b.send([1, 2, 3, 4, 5, 6, 7]) # 发送数据给conn_a
print('mian',os.getpid(), conn_b.recv())
#运行结果:
func 7940 [1, 2, 3, 4, 5, 6, 7]
mian 5180 ['a', 'b', 'c', 'd', 'e']
5、share
# 全局变量不可以进程共享
import multiprocessing
import os
data = []
def List():
global data
data.append(1)
data.append(2)
data.append(3)
print('p',os.getpid(),data)
if __name__ == '__main__':
p = multiprocessing.Process(target=List,args=()).start() # 子进程
data.append('a') # 主进程
data.append('b')
data.append('c')
print('main',os.getpid(),data)
#运行结果:
main 7328 ['a', 'b', 'c']
p 6068 [1, 2, 3]
6、queue
# 队列可以进程共享
import multiprocessing
import os
queue = multiprocessing.Queue()
# 注意队列只能单向,要么是父进程插入子进程取出,要么是子进程插入父进程取出
def func(myq):
print(os.getpid())
myq.put([1, 2, 3, 4]) # 子进程插入
if __name__ == '__main__':
print(os.getpid())
# queue.put(['a','b']) # 这里若是脚本父进程先插入了,子进程就没法再插入了
p = multiprocessing.Process(target=func, args=(queue,))
p.start()
print(queue.get()) # 脚本父进程取出
#运行结果:
5768
7724
[1, 2, 3, 4]
7、queueplus
import multiprocessing
import os
queue = multiprocessing.Queue()
def adddata(queue, i): # 子进程调用的函数
queue.put(i)
print('put', os.getppid(), os.getpid(), i)
if __name__ == '__main__': # 脚本父进程
mylist = []
for i in range(10):
p = multiprocessing.Process(target=adddata, args=(queue, i)) # 子进程
p.start()
# print(queue.get())
mylist.append(queue.get()) # get拿不到东西会一直等待
#运行结果:
put 3920 5284 0
put 3920 2980 1
put 3920 7636 2
put 3920 5216 3
put 3920 6528 4
put 3920 7492 5
put 3920 7284 6
put 3920 5968 7
put 3920 5376 8
put 3920 4208 9
8、进程数据共享
import multiprocessing
def func(num):
num.value = 10
if __name__ == '__main__':
# multiprocessing.Value可以在不同进程之间共享数据
num = multiprocessing.Value('d', 1) # double float
print(num.value) # 单单num返回的结果 Synchronized wrapper for c_double(1.0)
p = multiprocessing.Process(target=func, args=(num,))
p.start()
p.join()
print(num.value)
#运行结果:
1.0
10.0
9、进程列表数组共享
import multiprocessing
def func(num):
num[2] = 9999
if __name__ == '__main__':
# 不同进程之间实现数组共享
num = multiprocessing.Array('i', [1, 2, 3, 4, 5, 6]) # i代表int类型
print(num[:])
p = multiprocessing.Process(target=func, args=(num,))
p.start()
p.join()
print(num[:])
#运行结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 9999, 4, 5, 6]
10、进程字典列表共享
import multiprocessing
def func(mydict, mylist):
mydict["熊"] = "动物"
mydict["刘亦菲"] = "美女"
mylist.append(11)
mylist.append(22)
mylist.append(33)
if __name__ == "__main__":
# with multiprocessing.Manager() as MG:
# mydict=MG.dict()
# mylist=MG.list(range(5))
mydict = multiprocessing.Manager().dict()
# [0,1,2,3,4]
mylist = multiprocessing.Manager().list(range(5))
p = multiprocessing.Process(target=func, args=(mydict, mylist))
p.start()
p.join()
print(mylist)
print(mydict)
#运行结果:
[0, 1, 2, 3, 4, 11, 22, 33]
{'熊': '动物', '刘亦菲': '美女'}
练习
1、管道进程
import multiprocessing
def M(conn):
while 1:
recv_ = conn.recv()
print('机器人收到:%s'%recv_)
if recv_ == "你好":
conn.send('我不好')
elif recv_ == "今天天气怎么样":
conn.send('请问你的手机助手,我不知道')
elif recv_ == "我帅吗":
conn.send('你自己不知道吗')
else:
conn.send('我在学习')
def P(conn):
y = 'y'
while y !='n':
input_ = input('人说:')
conn.send(input_)
print('机器人说:%s'%conn.recv())
conn.close()
if __name__ == "__main__":
conn_M,conn_P = multiprocessing.Pipe()
p_M = multiprocessing.Process(target=M,args=(conn_M,))
p_M.start()
P(conn_P)
#运行结果:
人说:你好
机器人收到:你好
机器人说:我不好
人说:今天天气怎么样
机器人收到:今天天气怎么样
机器人说:请问你的手机助手,我不知道
人说:我帅吗
机器人收到:我帅吗
机器人说:你自己不知道吗
人说:...
机器人收到:...
机器人说:我在学习
2、管道共享
import multiprocessing
def A(conn):
conn.send(['a', 'b', 'c', 'd', 'e']) #发送的数据
print('A',conn.recv()) #收到的数据
conn.close() #关闭
if __name__ == "__main__":
conn_a,conn_b = multiprocessing.Pipe()
p = multiprocessing.Process(target=A,args=(conn_a,))
p.start()
conn_b.send([1, 2, 3]) #发送数据给conn_a
print('main', conn_b.recv())
#运行结果:
A [1, 2, 3]
main ['a', 'b', 'c', 'd', 'e']
3、数组共享
import multiprocessing
def func(num):
num[1] = 999
if __name__ == "__main__":
#不同进程之间实现数组共享
num = multiprocessing.Array('i', [1, 2, 3]) # i代表int类型
print(num[:])
p = multiprocessing.Process(target=func, args=(num,))
p.start()
p.join()
print(num[:])
运行结果:
[1, 2, 3]
[1, 999, 3]
4、队列
import multiprocessing
import time
def PUT(q):
for i in range(10):
time.sleep(1)
q.put(100)
def GET(q):
while 1:
try:
print('GET',q.get(timeout = 5))
except:
print('队列中已经无法获取元素在5秒之内')
break
if __name__ == "__main__":
q = multiprocessing.Queue()
p1 = multiprocessing.Process(target= PUT, args=(q,))
p2 = multiprocessing.Process(target= GET, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
#运行结果:
GET 100
GET 100
GET 100
GET 100
GET 100
GET 100
GET 100
GET 100
GET 100
GET 100
队列中已经无法获取元素在5秒之内
网页‘爬’东西
import requests
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
} # 网页查找源代码中有 分成字典型
url = 'https://www.baidu.com/s?wd=%E7%95%99%E4%B8%8B%E9%82%AE%E7%AE%B1'# 网址
response = requests.get(url,headers=headers)
html = response.text
print(html)
#用正则来找需要的东西
import re
str_ = "网页地址或者爬出来东西的文件地址"
regex = re.compile("[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?")# 正则 这里是邮箱的正则
res = regex.findall(str_)
print(res)