本章内容:
本章示例:
示例13-1Multiprocessing模块创建进程
from multiprocessing import Process
import os,time
def test():
print(f'我是子进程,我的PIP是:{os.getpid()},我的父进程是:{os.getppid()}')
time.sleep(1)
lst=[]
if __name__ == '__main__':
print('主进程开始执行')
#创建5个子进程
for i in range(5):
p=Process(target=test)
#启动子进程
p.start()
#启动中的进程添加到列表中
lst.append(p)
for item in lst:
item.join()#阻塞主进程
print('主进程执行结束')
示例13-2Process类中常用的属性和方法
from multiprocessing import Process
import os,time
def sub_process(name):
print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
time.sleep(1)
def sub_process2(name):
print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
time.sleep(1)
if __name__ == '__main__':
print('父进程开始执行')
for i in range(5):
p1=Process(target=sub_process,args=('ysj',))
p2=Process(target=sub_process2,args=(18,))
p1.start()
p2.start()
print(p1.name,'是否执行完毕',p1.is_alive())
print(p2.name,'是否执行完毕',p2.is_alive())
print(p1.name,'pid是:',p1.pid)
print(p2.name,'pid是:',p2.pid)
p1.join()
p2.join()
print('父进程执行结束')
示例13-3Process类中常用的属性和方法2
from multiprocessing import Process
import os,time
def sub_process(name):
print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
time.sleep(1)
def sub_process2(name):
print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
time.sleep(1)
if __name__ == '__main__':
print('主进程开始执行')
for i in range(5):
p1=Process(target=sub_process,args=('ysj',))
p2=Process(target=sub_process2,args=(18,))
p1.start() #Process如果没有指定参数,会调用run方法
p2.start() #指定了参数后,会调用指定的方法
p1.terminate() #强制终止进程
p2.terminate()
print('主进程执行结束')
示例13-4使用Process子类创建进程
from multiprocessing import Process
import os,time
class SubProcess(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print(f'子进程的名称{self.name},PID:{os.getpid()},父进程的PID:{os.getppid()}')
if __name__ == '__main__':
print('主进程开始执行')
lst=[]
for i in range(1,6):
p1=SubProcess(f'进程:{i}')
p1.start()
lst.append(p1)
for item in lst:
item.join()
print('主进程执行结束')
示例13-5使用进程池-非阻塞方式
from multiprocessing import Pool
import time,os
def task(name):
print(f'子进程的PID:{os.getpid()},执行的任务:{name}')
time.sleep(1)
if __name__ == '__main__':
start=time.time()
print('主进程开始执行')
p=Pool(3)
for i in range(10):
p.apply_async(func=task,args=(i,))
p.close()
p.join()
print('所有子进程执行完毕,主进程执行结束')
print(time.time()-start)
示例13-6使用进程池-阻塞方式
from multiprocessing import Pool
import time,os
def task(name):
print(f'子进程的PID:{os.getpid()},执行的任务:{name}')
time.sleep(1)
if __name__ == '__main__':
start=time.time()
print('主进程开始执行')
p=Pool(3)
for i in range(10):
p.apply(func=task,args=(i,))
p.close()
p.join()
print('所有子进程执行完毕,主进程执行结束')
print(time.time()-start)
示例13-7多个进程之间数据是否共享
from multiprocessing import Process
a=100
def add():
print('子进程1开始执行')
global a
a+=30
print('a=',a)
print('子进程1执行完毕')
def sub():
print('子进程2开始执行')
global a
a-=50
print('a=',a)
print('子进程2执行完毕')
if __name__ == '__main__':
print('主进程开始执行')
print('a=',a)
p1=Process(target=add)
p2=Process(target=sub)
p1.start()
p2.start()
p1.join()
p2.join()
print('主进程执行结束')
print('a=',a)
示例13-8队列的基本使用
from multiprocessing import Queue
if __name__ == '__main__':
# 创建一个队列
q = Queue(3)
print('队列是否为空:', q.empty())
print('队列是否为满:', q.full())
# 向队列中添加消息
q.put('hello')
q.put('world')
print('队列是否为空:', q.empty())
print('队列是否为满:', q.full())
q.put('Python')
print('队列是否为空:', q.empty())
print('队列是否为满:', q.full())
print('队列当中有多少消息:', q.qsize())
#出队
print(q.get())
print('队列中信息个数:',q.qsize())
#入队
q.put_nowait('html')
# q.put_nowait('sql') #queue.Full
# q.put('sql') #不报错,一直等待,直到队列中有空位
#遍历
if not q.empty():
for i in range(q.qsize()):
print(q.get_nowait())
print('队列是否为空:',q.empty())
print('队列是否为满:',q.full())
print('队列当中有多少消息:', q.qsize())
此示例中macOS无法运行qsize()方法,暂时没有找到解决办法
示例13-9向已满的队列中添加元素
from multiprocessing import Queue
if __name__ == '__main__':
q=Queue(3)
q.put('hello')
q.put('world')
q.put('python')
q.put('html')
示例13-10设置put方法的参数
from multiprocessing import Queue
if __name__ == '__main__':
q=Queue(3)
q.put('hello')
q.put('world')
q.put('python')
q.put('html',block=True,timeout=2)
示例13-11使用队列实现进程之间的通信
from multiprocessing import Queue,Process
import time
a=100
def write_msg(q):
global a
if not q.full():
for i in range(6):
a-=10
q.put(a)
print('a入队时的值',a)
def read_msg(q):
time.sleep(1)
while not q.empty():
print('出队时a的值:',q.get())
if __name__ == '__main__':
print('主进程开始执行')
q=Queue()
p1=Process(target=write_msg,args=(q,))
p2=Process(target=read_msg,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print('主进程执行完毕')
示例13-12函数方式创建线程
import threading
from threading import Thread
import time
def test():
for i in range(3):
time.sleep(1)
print(f'线程{threading.current_thread().name}正在执行{i}')
if __name__ == '__main__':
start=time.time()
print('主线程开始执行')
lst=[Thread(target=test) for i in range(2)]
for item in lst:
item.start()
for item in lst:
item.join()
print(f'一共耗时:{time.time()-start}')
示例13-13使用Thread子类创建线程
import threading
from threading import Thread
import time
class SubThread(Thread):
def run(self):
for i in range(3):
time.sleep(1)
print(f'线程{threading.current_thread().name}正在执行{i}')
if __name__ == '__main__':
print('主进程开始执行')
lst=[SubThread() for i in range(2)]
for item in lst:
item.start()
for item in lst:
item.join()
print('主线程执行完毕')
示例13-14线程之间的数据是否共享
from threading import Thread
a=100
def add():
print('加线程开始执行')
global a
a+=30
print('a=',a)
print('加线程执行结束')
def sub():
print('减线程开始执行')
global a
a-=50
print('a=',a)
print('减线程执行结束')
if __name__ == '__main__':
print('主线程执行')
print('全局变量a=',a)
add=Thread(target=add)
sub=Thread(target=sub)
add.start()
sub.start()
add.join()
sub.join()
print('主线程执行结束')
示例13-15线程共享数据所带来的安全性问题
import threading
from threading import Thread
import time
ticket=50
def sale_ticket():
global ticket
for i in range(100):
if ticket>0:
print(f'{threading.current_thread().name}正在出售第{ticket}张票')
ticket-=1
time.sleep(1)
if __name__ == '__main__':
for i in range(3):
t=Thread(target=sale_ticket)
t.start()
示例13-16使用lock锁
import threading
from threading import Thread,Lock
import time
ticket=50
lock_obj=Lock()#创建锁对象
def sale_ticket():
global ticket
for i in range(100):
lock_obj.acquire()
if ticket>0:
print(f'{threading.current_thread().name}正在出售第{ticket}张票')
ticket-=1
time.sleep(1)
lock_obj.release()
if __name__ == '__main__':
for i in range(3):
t=Thread(target=sale_ticket)
t.start()
示例13-17使用队列实现生产者和消费者的问题
from queue import Queue
from threading import Thread
import time
#创建一个生产者类
class Producer(Thread):
def __init__(self,name,queue):
Thread.__init__(self,name=name)
self.queue=queue
def run(self):
for i in range(1,6):
print(f'{self.name}将产品{i}放入队列')
self.queue.put(i)
time.sleep(1)
print('生产者完成了所有数据的存放')
#创建一个消费者类:
class Consumer(Thread):
def __init__(self,name,queue):
Thread.__init__(self,name=name)
self.queue=queue
def run(self):
for i in range(5):
value=self.queue.get()
print(f'消费者线程:{self.name}取出了{value}')
print('----------消费者线程完成了所有数据的取出---------')
if __name__ == '__main__':
queue=Queue()
p=Producer('Producer',queue)
c=Consumer('Consumer',queue)
p.start()
c.start()
p.join()
c.join()
print('主线程执行结束')
注:本文中的内容和示例均出自@Python_子木的视频