-
进程池
# -*- coding:utf-8 -*-
# V : 3.7.4
from multiprocessing import Pool
import time
def func(i):
print(f'任务 {i} 开始时间为:{time.ctime()}')
time.sleep(10)
print(f'任务 {i} 结束时间为:{time.ctime()}')
if __name__ == '__main__':
# 创建进程池,默认为 CPU 的核数
pool = Pool(4) # 创建 4 个进程
for i in range(10):
# print(f'开始执行任务{i}')
time.sleep(1)
pool.apply_async(func, (i,))
# apply_async(self, func, args=(), kwds={})
# func : 需要执行的函数
# args : 传入的参数。以元组形式,只有一个参数需要加上逗号
# kwds : 传入的参数。以字典形式
pool.close() # 当进程池中不在有任务是关闭进程
pool.join() # 等待所有的子进程执行完毕
# 各进程之间的变量不共享,因为每个进程都有属于之间的独立空间
-
队列的常用方法
# -*- coding:utf-8 -*-
# V : 3.7.4
from multiprocessing import Queue
if __name__ == '__main__':
# 创建队列,默认为无限,
queue = Queue(4)
# queue.put(obj, block=True, timeout=None) # 插入元素,设置block为 True,timeout等待时间操作时,当队列满了的时候会报错
# queue.get(block=True, timeout=None) # 取出并删除元素,设置block为 True,timeout等待时间操作时,当队列没有时会报错
# queue.qsize() # 查看队列大小
# queue.full() # 判断队列是否也满,返回 True 或者 False
# queue.empty() # 判断队列是否已空,返回 True 或者 False
-
进程之间的通信
# -*- coding:utf-8 -*-
# V : 3.7.4
from multiprocessing import Process, Queue
import time
def write(q):
a = [1, 2, 3, 4, 5, 6]
for i in a:
print(f'开始写入队列{i}')
q.put(i)
time.sleep(1)
def read(q):
for i in range(q.qsize()):
print(f'开始读取队列的{q.get()}')
time.sleep(1)
if __name__ == '__main__':
q = Queue()
p_w = Process(target=write, args=(q,))
p_r = Process(target=read, args=(q,))
# 注意写入完在读取。不然会读取不完整
p_w.start()
p_w.join()
p_r.start()
p_r.join()
-
进程池之间的通信
# -*- coding:utf-8 -*-
# V : 3.7.4
from multiprocessing import Process, Pool, Manager
import time
def write(q):
a = [1, 2, 3, 4, 5, 6]
for i in a:
print(f'开始写入队列{i}')
q.put(i)
time.sleep(1)
def read(q):
for i in range(q.qsize()):
print(f'开始读取队列的{q.get()}')
time.sleep(1)
if __name__ == '__main__':
q = Manager().Queue() # 进程池使用的是 Manger() 中的 Queue() 方法
p = Pool(3) # 创建三个进程
p.apply(write, (q,)) # 必须使用 apply 方法,使其阻塞以写入所有的队列
p.apply(read, (q,))
p.close()
p.join()
-
thrending 线程
# -*- coding:utf-8 -*-
# V : 3.7.4
import threading
import time
def func1(name, wait):
print(f'线程{name}开始运行')
time.sleep(wait)
print(f'线程{name}结束运行')
def func2(name, wait):
print(f'线程{name}开始运行')
time.sleep(wait)
print(f'线程{name}结束运行')
if __name__ == '__main__':
print('主程序开始运行')
# 创建线程
t1 = threading.Thread(target=func1, args=('func1', 2))
t2 = threading.Thread(target=func2, args=('func2', 5))
# 开始运行
t1.start()
t2.start()
# 结束运行
t1.join()
t2.join()
-
线程之间共享全局变量
# -*- coding:utf-8 -*-
# V : 3.7.4
import threading
import sys
num = 13
def func1():
global num
num += 5
print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
def func2():
global num
print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
if __name__ == '__main__':
t1 = threading.Thread(target=func1, args=())
t2 = threading.Thread(target=func2, args=())
# 线程属于一个内存空间。同时执行会出现抢占 CPU 的情况,会导致数据出现混乱
t1.start()
t1.join()
t2.start()
t2.join()
-
线程之间应该有一把锁
# -*- coding:utf-8 -*-
# V : 3.7.4
import threading
import sys
num = 0
look = threading.Lock() # 创建一把锁
def func1():
global num
for i in range(119999):
look.acquire() # 上锁
num += 1
look.release() # 解锁
print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
def func2():
global num
for i in range(119999):
look.acquire() # 上锁
num += 1
look.release() # 解锁
print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
if __name__ == '__main__':
t1 = threading.Thread(target=func1, args=())
t2 = threading.Thread(target=func2, args=())
# 由于线程之间加了锁,所以不用担心数据混乱
# 锁应该加在 数值 改变的地方
t1.start()
t2.start()
t1.join()
t2.join()
-
线程间的同步锁
# -*- coding:utf-8 -*-
# V : 3.7.4
from threading import Thread, Lock
import time
# 创建三把锁
lock1 = Lock()
lock2 = Lock()
lock3 = Lock()
# 为 其中的两把锁加锁
lock2.acquire()
lock3.acquire()
class test1(Thread):
def run(self) -> None:
while 1:
if lock1.acquire():
print('lock1 加锁,解锁 lock2')
time.sleep(1)
lock2.release()
class test2(Thread):
def run(self) -> None:
while 1:
if lock2.acquire():
print('lock2 加锁,解锁 lock3')
time.sleep(1)
lock3.release()
class test3(Thread):
def run(self) -> None:
while 1:
if lock3.acquire():
print('lock3 加锁,解锁 lock1,开始下一个循环')
time.sleep(1)
lock1.release()
if __name__ == '__main__':
t1 = test1()
t2 = test2()
t3 = test3()
# 由于加锁了,数据不会混乱。
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
-
生产者消费者模式
# -*- coding:utf-8 -*-
# V : 3.7.4
from threading import Thread
from queue import Queue
import time
class Producer(Thread):
def run(self) -> None:
global q
while 1:
if q.qsize() < 100:
for i in range(50):
msg = f'生产第 {i} 个产品'
q.put(msg)
print(msg)
time.sleep(1)
class Consumer(Thread):
def run(self) -> None:
global q
while 1:
if q.qsize() > 30:
for i in range(20):
msg = f'消费第 {i} 个产品'
q.get()
print(msg)
time.sleep(1)
if __name__ == '__main__':
q = Queue()
t1 = Producer()
t2 = Consumer()
t1.start()
time.sleep(2)
t2.start()