1.multiprocessing
利用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则会独立运行
2.join
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’)
‘’’
轮流执行
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
‘’’
#进程通信
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() # 创建一个管道,有两个口
# print(id(conn_a),id(conn_b))
# print(type(conn_a), type(conn_b)) #multiprocessing.connection.Connection链接,意思就是连接口
# 相当于在进程中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())
#队列可以进程共享
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()) # 脚本父进程取出
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拿不到东西会一直等待
task_done()
之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。
若当前一个join()正在阻塞,它在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)。
join()
阻塞调用线程,直到队列中的所有任务被处理掉。
只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。
put(item[, block[, timeout]])
将item放入队列中。
如果可选的参数block为True且timeout为空对象(默认的情况,阻塞调用,无超时)。
如果timeout是个正整数,阻塞调用进程最多timeout秒,如果一直无空空间可用,抛出Full异常(带超时的阻塞调用)。
如果block为False,如果有空闲空间可用将数据放入队列,否则立即抛出
get([block[, timeout]])
从队列中移除并返回一个数据。block跟timeout参数同put方法
其非阻塞方法为`get_nowait()`相当与get(False)
empty()
如果队列为空,返回True,反之返回False