Lexan 2020-06-12
进程之间的共享数据(列表list 或者 字典dict等)
from multiprocessing import Process,Manager,Lock def work(data,lock): # 1.正常写法 """ lock.acquire() # data["count"] -= 1 data[0] += 1 lock.release() """ # 2.使用with 语法简化上锁解锁操作 with lock: data[0] += 1 if __name__ == "__main__": m = Manager() # 创建一个共享的字典 data = m.dict( {"count":20000} ) # 创建一个共享的列表 data = m.list([1,2,3]) # print(data) lst = [] lock = Lock() for i in range(100): p = Process(target=work,args=(data,lock)) p.start() lst.append(p) # 确保所有的进程执行完毕,然后在向下运行,打印数据,否则报错; for i in lst: i.join() print(data) # [101, 2, 3]
#进程是资源分配的最小单位 #线程是计算机中调度的最小单位 #线程的缘起 资源分配需要分配内存空间,分配cpu: 分配的内存空间存放着临时要处理的数据等,比如要执行的代码,数据 而这些内存空间是有限的,不能无限分配 目前配置高的主机,5万个并发已是上限.线程概念应用而生. #线程的特点 线程是比较轻量级,能干更多的活,一个进程中的所有线程资源是共享的. 一个进程至少有一个线程在工作
1 . 一份进程资源中可以包含多个线程
from threading import Thread from multiprocessing import Process import os """ def func(num): print(‘当前线程{},所归属的进程id号{}‘.format(os.getpid(),num)) for i in range(10): # 异步创建10个子线程 t = Thread(target=func,args=(i,)) t.start() # 主线程执行任务 print(os.getpid())
2 . 并发多线程和多进程, 多线程的速度更快,谨慎选择创建进程的数量
import time def func(num): print(‘当前线程{},所归属的进程id号{}‘.format(os.getpid(),num)) if __name__==‘__main__‘: """ #记录开始时间 starttime=time.time() lst=[] 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) """ """ #记录开始时间 starttime=time.time() lst=[] for i in range(1000): p=Process(target=func,args=(i,)) p.start() lst.append(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)
4 . 用自定义类的方法创建线程
一定要继承父类Thread
手动调用父类的构造方法
class MyThread(Thread): def __init__(self,name): # 手动调用父类的构造方法 super().__init__() self.name = name def run(self): time.sleep(1) print("当前进程正在执行runing ... " , self.name) if __name__ == "__main__": t = MyThread("机器今天会再次爆炸么?") t.start() print("主线程执行结束 ... ")
5 . 线程相关的函数
线程.is_alive() 检测线程是否仍然存在 线程.setName() 设置线程名字 线程.getName() 获取线程名字 1.currentThread().ident 查看线程id号 2.enumerate() 返回目前正在运行的线程列表 3.activeCount() 返回目前正在运行的线程数量
def func(): time.sleep(1) if __name__ == "__main__": t = Thread(target=func) # print(t) t.start() # print(t , type(t)) print(t.is_alive()) # False print(t.getName()) t.setName("xboyww") print(t.getName())
currentThread().ident 查看线程id号
def func(): print("子线程id",currentThread().ident , os.getpid()) if __name__ == "__main__": Thread(target=func).start() print("主线程id",currentThread().ident , os.getpid())
enumerate() 返回目前正在运行的线程列表
acctiveCount() 返回目前正在运行的线程数量
from threading import enumerate from threading import activeCount # (了解) def func(): print("子线程id",currentThread().ident , os.getpid()) time.sleep(0.5) if __name__ == "__main__": for i in range(10): Thread(target=func).start() lst = enumerate() # 子线程10 + 主线程1个 = 11 # print(lst ,len(lst)) # 3.activeCount() 返回目前正在运行的线程数量 print( activeCount() )
6 .守护线程
等待所有线程全部执行完毕之后,在自己终止,守护的是所有线程
线程名.setDaemon(True)
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 ... ") t1 = Thread(target=func1) t2 = Thread(target=func2) # 在start调用之前,设置守护线程 t1.setDaemon(True) t1.start() t2.start() print("主线程执行结束 ... ")
7 . 用 Lock 保证数据安全
from threading import Lock,Thread import time n = 0 def func1(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 # func1() # func2() # print(n) if __name__ == "__main__": lst = [] lock = Lock() time1 = 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() time2 = time.time() print("主线程执行结束..." , n ,time2 - time1)
8 . 信号量 Semaphore(线程)
from threading import Semaphore,Thread import time def func(i,sm): with sm: print(i) time.sleep(3) if __name__ == "__main__": sm = Semaphore(5) for i in range(20): Thread(target=func,args=(i,sm)).start() """ 总结: 在创建线程的时候是异步创建 在执行任务的时候,因为Semaphore加了锁,所以线程之间变成了同步 """