一.Manager (list 列表 , dict 字典) 进程之间的共享数据(列表或者字典等)
from multiprocessing import Process,Manager,Lock
(1) 基本语法
def work(data,lcok): # 1.正常写法 ''' #上锁 lock.acquire() # 修改数据 dic['count'] -=1 # 解锁 lock.release() ''' # 2.使用with语法可以简化上锁和解锁两步操作 with lock: data[0]+=1 if __name__=='__main__': lst=[] lock = Lock() m = Manager() data = m.dict( {'count':2000 } ) data = m.list( [1,2,3] ) for i in range(50): p = Process(target=work,args=(data,lock)) p.stat() lst.append(p) # 确保所有程序执行完毕之后,再向下执行,打印数据,否则报错. for i in lst: i.join() print(data)
二.线程
- 进程:资源分配的最小单位
- 线程:cpu执行程序的最小单位
from threading import Thread from multiprocessing import Process import os,time,random
(1) 一个进程资源中可以包含多个线程
def func(num): time.sleep(random.uniform(0.1,1)) print("当前进程{},参数是{}".format(os.getpid(),num)) for i in range(10): t = Thread(target=func,args=(i,)) t.start() print(os.getpid())
(2) 并发的多线程和多进程谁的速度快? 多线程!
<1>并发的多线程
def func(num): print('当前进程{},参数是{}'.format(os.getpid(),num)) if __name__=='__main__': lst = [] # 记录开始时间 startime = time.time() for i in range(1000): t = Thread(target=func,args=(i,)) t.start() lst.append(t) #等待所有子线程执行完毕 for i in lst: i.join() # 计算结束时间 endtime = time.time() print('多线程执行时间',(endtime-starttime))
<2>并发的多进程
def func(): print('当前进程{},参数是{}'.format(os.getpid(),num)) if __name__ =='__main__': lst = [] # 记录开始时间 starttime = time.time() for i in range(1000): p = Process(target=func,args=(i,)) p.start() lst.appen(p) # 等到所有的子进程执行完毕 for i in lst: i.join() # 计算结束时间 endtime = time.time() print('多进程执行时间',(endtime-starttime))
<3>多线程之间,共享同一份进程资源
num = 1000 def func(): global num num -=1 for i in range(1000): t = Thread(target=func) t.start() print(num)
三.用类定义线程
from threading import Thread, import os,time
(1)基本语法:
class MyThread(Thread): def __init__(self,name): # 手动调用父类方法 super().__init__() self.name = name def run(self): time.sleep(1) print('当前进程号码是{},名字是{}'.format(os.getpid(),self.name)) if __name__=='__main__': t = MyThread('当时是一个线程') t.start() print('主线程运行结束 ... ')
四.线程的相关函数
- 线程.is_alive() 检测线程是否仍然存在
- 线程.setName() 设置线程名字
- 线程.getName() 获取线程名字
- 1.currentThread().ident 查看线程id号
- 2.enumerate() 返回目前正在运行的线程列表
- 3.activeCount() 返回目前正在运行的线程数量
def func(): time.sleep(1) if __name__=='__main__': t = Thread(target=func) t.start() # 检测线程是否仍然存在 print(t.is_alive()) # 获取线程名字 print(t.getName()) # Thread-1 # 设置线程名字 t.setName('lx') # 获取线程名字 print(t.getName())
(1)currentThread)().ident 查看线程id号
from threading import currentThread # 1.currentThread().ident 查看线程id号 def func(): print('子线程的线程id{}'.format(currentThread().ident)) if __name__ =='__main__': Thread(target=func).start() print('主线程的线程id{}'.format(currentThread().ident))
(2)enumerate() 返回目前正在运行的线程列表
(3)activeCount() 返回目前正在运行的线程数量(了解)
from threading import enumerate from threading import activeCount def func(): print('子线程的线程id{}'.format(currentThread()ident)) time.sleep(0.5) if __name__=='__main__': for i in range(10): Thread(target=func).start() lst = enumerate() # 主线程 + 10个子线程 print(lst,len(lst)) # 3.activeCount()返回目前正在运行的线程数量 print(activeCount())
五.守护线程
- 守护线程:等待所有线程全部执行完毕之后,自己在终止,守护所有线程
from threading import Thread import time def func1: while True : time.sleep(0.5) print('func1') def func2(): print('我是func2 start ... ') time.sleep(3) print('我是func2 end ... ') def func3(): print('我是func3 start ... ') time.sleep(5) print('我是func3 end ... ') if __name__=='__main__': t1 = Thread(target=func1) t2 = Thread(target=func2) t3 = Thread(target=func3) # 在start调用之前,设置线程为守护线程 t1.setDaemon(True) t1.start() t2.start() t3.start() print('主线程序结束 ... ')
六.线程中安全问题 Lock
from threading import Lock,Thread import time n = 0 def func(lock): global n lock.acquire() for i in range(1000000): n += 1 lock.release() def func2(lock): global n # with 自动完成上锁+解锁 with lock: for i in range(1000000): n -= 1 if __name__=='__main__': lst = [] lcok = Lock() startime = time.time() for i in range(10): t1 = Thread(target=func1,args=(lock,)) t2 = Thread(target=func2,args=(lock,)) t1.start() t2.start() lst.append(t1) lst.append(t2) for i in lst: i.join() endtime = time.time() print('主线程执行结束 ... 打印{}时间是{}'.format(n,endtime-startime))
七.信号量 Semaphore(线程)
from threading import Semaphore,Thread import time def func(i,sm): # 上锁 + 解锁 with sm: print(i) time.sleep(3) if __name__=='__main__': # 支持同一时间,5 个线程上锁 sm = Semaphore(5) for i in range(20): Thread(target=func,args=(i,sm)).start()
- 再创建线程的时候是异步创建
- 在执行任务时,遇到Semaphore进行上锁,会编程同步程序