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则会独立运行
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 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()
简单通信
# 进程通信
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
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)
'''
全局变量不共享
1809 ['a', 'b', 'c']
1810 [1, 2, 3]
'''
队列
Queue.qsize()
返回队列的大致大小。注意,qsize()> 0不保证后续的get()不会阻塞,qsize()<maxsize也不保证put()不会阻塞。
Queue.empty()
True如果队列为空False则返回,否则返回。如果empty()返回True,则不保证对put()的后续调用不会阻塞。类似地,如果empty()返回False,则不保证对get()的后续调用不会阻塞。
Queue.full()
True如果队列已满,False则返回,否则返回。如果full()返回True,则不保证对get()的后续调用不会阻塞。同样,如果full()返回False,则不保证对put()的后续调用不会阻塞。
Queue.put(item,block = True,timeout = None )
将项目放入队列。如果可选的args 块为true且timeout为 None(默认值),则在必要时阻塞,直到有空闲插槽可用。如果 timeout是一个正数,它会阻止最多超时秒,Full如果在该时间内没有可用的空闲槽,则会引发异常。否则(块为假),如果空闲插槽立即可用,则将项目放在队列上,否则引发Full异常(在这种情况下忽略超时)。
Queue.put_nowait(项目)
相当于。put(item, False)
Queue.get(block = True,timeout = None )
从队列中删除并返回一个项目。如果可选的args 块为true且 timeout为None(默认值),则在必要时阻止,直到某个项可用为止。如果timeout是一个正数,它会阻止最多超时秒,Empty如果在该时间内没有可用项,则会引发异常。否则(块为假),如果一个项立即可用则返回一个项,否则引发Empty异常(在这种情况下忽略超时)。
在POSIX系统上3.0以及Windows上的所有版本之前,如果 block为true且timeout为None,则此操作将进入基础锁的不间断等待。这意味着不会发生异常,特别是SIGINT不会触发a KeyboardInterrupt。
Queue.get_nowait()
相当于get(False)。
提供了两种方法来支持跟踪守护进程消费者线程是否已完全处理入队任务。
Queue.task_done()
表示以前排队的任务已完成。由队列使用者线程使用。对于每个get()用于获取任务的人,后续调用 task_done()告诉队列任务的处理完成。
如果a join()当前正在阻止,则它将在所有项目都已处理后恢复(意味着task_done()已收到已put()进入队列的每个项目的呼叫)。
提出一个ValueErrorif被调用次数超过队列中放置的项目。
Queue.join()
阻止直到队列中的所有项目都已获取并处理完毕。
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()) # 脚本父进程取出