"""
multiprocessing模块
from multiprocessing import Process #Process类创建进程
Process(group=None,target,name,args,kwargs)
参数
group:表分组,实际上不使用,值默认为None
target:表子进程要执行的认为,支持函数名
name:表子进程的名称
args:表调用函数的位置参数,以元组形成进行传递
kwargs:表调用函数的关键字参数,以字典的形式进行传递
类的继承 创建子进程
class 子进程(Process)
pass
类的方法,属性
name 当前进程实例别名,默认Process-N
pid 当前进程对象的pid值
is_alive() 进程是否执行完,若没执行完返回True,反之False
join(timeout) 等待进程结束timeout秒
start() 启动进程
run() 若没有指定targe参数,则启动进程后,调用父类中的run方法
terminate() 强制终止进程
from multiprocessing import Pool #Pool类用于进程池
进程池对象=Pool(N)#进程池一次可以执行最多N个进程。假设N=3,需要完成10个任务,进程池一次最多执行3个任务,4次即完成全部任务
apply_async(func,args,kwargs) 使用非阻塞方式调用函数func
apply(func,args,kwargs) 使用阻塞方式调用函数func
close() 关闭进程池,不再接收新任务
terminate() 不管任务是否完成,立即终止
join() 阻塞主进程,必须在terminate()或close()之后使用
进程之间数据不共享
进程执行顺序不定,由cpu调度而定
from multiprocessing import Queue #Queue用于队列
队列对象=Queue(N)#没有指定参数,则接收数据数无上限
qsize() 获取当前队列包含的消息数量
empty() 判断队列是否为空,为空结果为True,否则为False
full() 判断队列是否满了,满了结果为True,否则为False
get(block=True) 获取队列中的一条消息,然后从队列中移除,block默认值为True
get_nowait() 相当于get(block=False),消息队列为空时报错
put(item,block=True,timeout) 将item消息放入队列,block默认为True
put_nowait(item) 相当于put(item,block=False)
进程之间可以通过队列实现数据共享,队列是一种先进先出的数据结构
两个进程,分别负责数据的入队和出队,使数据能通信于进程间
from threading import Thread #Thread用于线程
Thread(group,target,name,args,kwargs)
参数
group 创建线程对象的进程组
target 创建的线程对象所要执行的目标函数
name 创建线程对象的名称,默认Thread-n
args 用元组以位置参数的形式传入target对应函数的参数
kwargs 用字典以关键字参数形式传入target对应函数的参数
类的继承创建线程
改写run(self)方法→target 创建的线程对象所要执行的目标函数
线程之间数据共享→同进程一样,线程执行顺序不定,可能出现数据错乱
from multiprocessing import Lock
锁对象=Lock()
acquire() 锁定状态
release() 非锁定状态
生产者与消费者模式 防止出现队列已满生产者扔再生产;队列已空消费者仍在消费
from queue import Queue
队列对象=Queue()
put(item) 向队列中放置数据,若队列为满,则阻塞
get() 从队列中取走数据,若队列为空,则阻塞
join() 若队列不为空,则等待队列变为空
task_done() 消费者从队列中取走一项数据,当队列变为空时,唤醒调用join()的线程
"""
import threading
from multiprocessing import Process
import os
def process_son(task):
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')#pid是进程标识符,是操作系统用于标识每个进程的唯一数字标识符
print(task)
#由于每个子进程是通过导入所在脚本的模块实现模块中函数的调用的,为了避免将创建子进程的语句也被导入,这样会造成无限循环创建子进程
if __name__ == '__main__':#python禁止了在子进程中再创建子进程,创建子进程的语句必须在if __name__=='__main__'语句之后定义
print("父进程运行")
process_list=[]
for i in range(3):
process=Process(target=process_son,args=(i,))#创建子进程
process.start()#启动子进程
print(process.name,process.pid,"开始运行")
process_list.append(process)
for item in process_list:
if item.is_alive():
print(item.name, item.pid, "未执行完毕")
item.join()#阻塞父进程,父进程,各个子进程间相互独立
else:
print(item.name, item.pid, "执行完毕")
process_empty=Process()#无target参数,不执行自定义的run
process_empty.start()
print(process_empty.pid)
process_stop=Process(target=process_son,args=('stop',))
process_stop.start()
print(process_stop.name,process_stop.pid)
process_stop.terminate()
print("父进程运行结束")
class Cless_process_son(Process):
def __init__(self,task):#自带self参数
super().__init__()
self.task=task
def run(self):#重写run方法
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')
print(self.task)
if __name__ == '__main__':
print("父进程运行")
process_list=[]
for i in range(3):
process=Cless_process_son(i)
process.start()
print(process.name,process.pid,"开始运行")
process_list.append(process)
for item in process_list:
if item.is_alive():
print(item.name,item.pid,"未执行完毕")
item.join()
else:
print(item.name,item.pid,"执行完毕")
process_stop=Cless_process_son('stop')
process_stop.start()
process_stop.terminate()
print("父进程运行结束")
from multiprocessing import Pool
import time
def pool_process_son0(str):
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')
print(str)
time.sleep(3)#停顿4次,10个任务,进程池一次最多执行3个任务,4次即完成全部任务
if __name__ == '__main__':
print("父进程运行")
p=Pool(3)#创建进程池
for i in range(10):#总计10个任务
str=i
p.apply_async(func=pool_process_son0, args=(str,))#以非阻塞方式调用
p.close()#关闭进程池,结束任务
p.join()#阻塞父进程,待所有子进程执行完毕
print("父进程运行结束")
def pool_process_son1(str):
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')
print(str)
time.sleep(1) #阻塞方式调用是待当前任务完成后再执行下一任务 停顿10次
if __name__ == '__main__':
print("父进程运行")
p = Pool(3) # 创建进程池
for i in range(10):
str = i
p.apply(func=pool_process_son1, args=(str,)) # 以阻塞方式调用
p.close() # 关闭进程池,结束任务
p.join() # 阻塞父进程,待所有子进程执行完毕
print("父进程运行结束")
number=100
def addition_process_son():
global number
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')
number+=30
print("addition result number:",number)
def subtraction_process_son():
global number
print(f'子进程运行,子进程pid:{os.getpid()},父进程pid:{os.getppid()}')
number-=60
print("subtraction result number:",number)
if __name__ == '__main__':
print("父进程运行")
print("number:",number)
process1=Process(target=addition_process_son)
process2=Process(target=subtraction_process_son)
process1.start()
process2.start()
process1.join()
process2.join()
print("number:",number)
print("父进程运行结束")
from multiprocessing import Queue
if __name__ == '__main__':
queue=Queue(3)#创建队列 最多可接收3个数据
print(queue.empty())
print(queue.full())
queue.put('first')
queue.put('second')
queue.put('third')
print(queue.empty())
print(queue.full())
print(queue.qsize())
print(queue.get())
queue.put_nowait('fourth')#也可用put
#queue.put_nowait('fifth')#队列已满,put_nowait入队报错 block=False要求立马入队,否则报错
#queue.put('fifth',timeout=3)#队列已满,put入队不报错,等待timeout,若仍没有数据出队,则报错 block=True等待入队
if not queue.empty():#if-for遍历队列出队
for i in range(queue.qsize()):
print(queue.get_nowait())
#print(queue.get_nowait())#队列为空,get出队报错 block=False要求立马入队,否则报错
#print(queue.get())#队列为空,get出队不报错 block=True等待入队
def enqueue(queue):#入队
while not queue.full():
message='message'
queue.put(message)
print('enqueue:', message)
def dequeue(queue):#出队
while not queue.empty():
print('dequeue:',queue.get())
if __name__ == '__main__':
print("父进程运行")
queue=Queue(1)
process_enqueue=Process(target=enqueue,args=(queue,))
process_dequeue=Process(target=dequeue,args=(queue,))
process_enqueue.start()
process_enqueue.join()
process_dequeue.start()
process_dequeue.join()
print("父进程运行结束")
from threading import Thread
def thread():
for i in range(3):
print(f'{threading.current_thread().name}执行{i}')#线程是进程的基本单位,一进程可有多线程,线程,进程默认名称中的n为之共用
if __name__ == '__main__':
print("主线程运行")
thread_list=[Thread(target=thread) for i in range(3)]#创建线程于列表中
for item in thread_list:
item.start()#启动线程
for item in thread_list:
item.join()#阻塞主线程
print("主线程运行结束")
class Class_thread(Thread):
def run(self):#重写run方法
for i in range(3):
print(f'{threading.current_thread().name}执行{i}')
if __name__ == '__main__':
print("主线程运行")
thread_list = [Class_thread() for i in range(3)] # 创建线程于列表中
for item in thread_list:
item.start() # 启动线程
for item in thread_list:
item.join() # 阻塞主线程
print("主线程运行结束")
number=100
def addition_thread():
global number
number+=30
print(f'{threading.current_thread().name}执行 result:{number}' )
def subtraction_thread():
global number
number-=60
print(f'{threading.current_thread().name}执行 result:{number}')
if __name__ == '__main__':
print("主线程运行")
print("number:", number)
add=Thread(target=addition_thread)
sub=Thread(target=subtraction_thread)
add.start()
sub.start()
add.join()
sub.join()
print("number:", number)
print("父进程运行结束")
#售票举例
from multiprocessing import Lock
ticket=50#总计张票
lock=Lock()#创建锁对象
def sale_ticket():
global ticket
for i in range(100):#每个售票窗口(线程)需处理100人
lock.acquire()#上锁
if ticket>0:
ticket-=1
print(f'{threading.current_thread().name} 余{ticket}票')
lock.release()#解锁
if __name__ == '__main__':
print("开售")
for i in range(3):#三个售票窗口(线程)
window=Thread(target=sale_ticket)
window.start()
window.join()
if ticket==0:
print("售空")
from queue import Queue
class Producer(Thread):#创建生产者类
def __init__(self,queue):
super().__init__()
self.queue=queue
def run(self):
for i in range(1,6):
self.queue.put(i)
print(f'{self.name}生产第{i}件产品')
print("生产者完成生产")
class Consumer(Thread):#创建消费者类
def __init__(self,queue):
super().__init__()
self.queue=queue
def run(self):
for i in range(1,6):
self.queue.get(i)
print(f'{self.name}取走第{i}件产品')
print("消费者完成消费")
if __name__ == '__main__':
print("主线程运行")
queue=Queue()#创建储物仓库
producer_Thread=Producer(queue)
producer_Thread.name='producer'
consumer_Thread=Consumer(queue)
consumer_Thread.name='consumer'
producer_Thread.start()
consumer_Thread.start()
producer_Thread.join()
consumer_Thread.join()
print("主线程运行结束")
运行结果
进程执行顺序不定,由cpu调度而定,故每次运行部分输出结果会有不同