文章目录
进程
进程创建
from multiprocessing import Process
def run_proc(name, age, **kwargs):
'''
子进程要执行的代码
'''
print("{} is {}".format(name, age))
print(kwargs)
print("子进程pid:{}".format(os.getpid()))
p = Process(target=run_proc, args=("子进程", 1), kwargs={"nihao": 1}) # 子进程对象 不加()
p.start() # 开启子进程
进程间通信Queue
from multiprocessing import Queue, Process
import time
# 先写
def write(q: Queue):
for i in range(4):
q.put(i)
print("%d is put" % i)
# 后读
def read(q: Queue):
while True:
if not q.empty():
value = q.get(True) # True 表示空的时候阻塞
print("%d is get" % value)
else:
break
if __name__ == '__main__':
q = Queue(10) # 初始化一个Queue对象,最多接受10个put
w = Process(target=write, args=(q,)) # 元组 一个数据时 必须加 ,
r = Process(target=read, args=(q,))
w.start()
# 防止写进程还没写完数据,读进程就开始读数据
time.sleep(1)
r.start()
进程池的使用
from multiprocessing import Pool
import time, random, os
def worker(msg):
time_start = time.time()
# 3个消费者 执行9个生产者任务
print("%s 开始执行,进程号为 %d" % (msg, os.getpid()))
# random.random() 随机生成0-1之间的浮点数
time.sleep(random.random() * 2)
time_stop = time.time()
print(msg, "执行完毕,耗时%0.2f" % (time_stop - time_start))
if __name__ == '__main__':
po = Pool(3) # 创建一个进程池,最多有三个进程
for i in range(10):
# 每次循环将会用 空闲出来的子进程去调用目标
po.apply_async(worker, (i,)) # async异步 传参 函数名不加() , 元组
print("-----start------")
# 注: 必须先close 才能join
po.close() # 关闭进程池,关闭后po不再接受新的任务
po.join() # 等待po中所有的子进程执行完毕
print("-----end------")
进程池之间的通信(和进程间的通信略有不同)
from multiprocessing import Manager, Pool
import os, time
def reader(q):
print("reader pid %s, father pid %s" % (os.getpid(), os.getppid()))
for i in range(q.qsize()):
print("reader 获取到的消息 %s" % q.get(True))
def writer(q):
print("writer pid %s, father pid %s" % (os.getpid(), os.getppid()))
for i in "tz-xuge":
q.put(i)
if __name__ == '__main__':
print("父进程pid", os.getpid())
q = Manager().Queue() # 进程池间的通讯 队列
po = Pool()
po.apply_async(writer, (q,))
time.sleep(1)
po.apply_async(reader, (q,))
po.close()
po.join()
线程
线程创建
import time
from threading import Thread
def run_proc():
print("hello thread!")
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
th = Thread(target=run_proc) # 只传方法名,不加括号
th.start() # 线程开始运行
查看线程数量
import threading
from threading import Thread
import time
def run_proc():
for i in range(10):
print("num")
time.sleep(1)
if __name__ == '__main__':
th = Thread(target=run_proc)
th.start()
while True:
length = len(threading.enumerate())
print(length) # 查看线程的数量 -> 2
if length <= 1:
break
print("end")
命令方法
ps -elLf | grep "关键词"
top “按H来查看线程”
线程的封装(重写run方法)
import time
from threading import Thread
# 自己重写的线程
class MyThread(Thread):
def run(self) -> None:
for i in range(3):
print("I'm " + self.name + ' @ ' + str(i))
if __name__ == '__main__':
for i in range(2):
th = MyThread()
th.start()
多线程-共享全局变量(进程不共享全局变量)
from threading import Thread
def test1():
global num
num += 1
print("test1 " + str(num))
def test2():
global num
num += 1
print("test2 " + str(num))
if __name__ == '__main__':
num = 100
th1 = Thread(target=test1)
th2 = Thread(target=test2)
th1.start()
th2.start()
print("main " + str(num))
互斥锁-解决共享变量的问题(类似OS的PV操作)
import threading
from threading import Thread
def test1(count):
global num
for i in range(count):
mutex.acquire() # 加锁
num += 1
mutex.release() # 释放锁
print("test1 " + str(num))
def test2(count):
global num
for i in range(count):
mutex.acquire() # 加锁
num += 1
mutex.release() # 释放锁
print("test2 " + str(num))
if __name__ == '__main__':
mutex = threading.Lock() # 这是一个全局的锁
num = 0
th1 = Thread(target=test1, args=(100000,))
th2 = Thread(target=test2, args=(100000,))
th1.start()
th2.start()
while len(threading.enumerate()) != 1:
continue # 有线程没执行完就继续
print("main " + str(num)) # 打印的值为最后一个线程修改过的值
注:这是没加锁的运行结果
注:这是加锁的运行结果