‘‘‘并发:同一个时间段内运行多个程序的能力 进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据集、进程控制块三部分组成 程序:食谱数据集:鸡蛋、牛奶、糖等进程控制块:记下食谱做到哪一步了 线程:最小的执行单元,程序中具体代码 比如:食谱中的具体操作方法进程:最小的资源管理单元,线程,数据等等 比如:整个食谱 切换的操作者:操作系统进程/线程切换原则: 1、时间片 2、遇到IO操作切换 代码执行input()函数时,本身不占cpu了,输入完成后再切回来。conn,client_addr = sock.accept()执行后不占cpu了, 开启了另一个有关监听的线程,当接收到数据是再切给accept 串行、并行、并发并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集 IO密集型任务:程序存在大量IO操作计算密集型任务:程序存在大量计算操作 对于PYTHON的多线程处理: IO密集型任务有优势 计算密集型任务不推荐使用多线程 ‘‘‘ 多线程
import threading import time def foo(n): print(‘>>>>>%s‘ %n) time.sleep(3) def bar(n): time.sleep(5) print(‘>>>>>%s‘ %n) s = time.time() t1 = threading.Thread(target=foo,args=(2,)) t1.start() # .start()方法激活线程,可以去抢cpu执行 t2 = threading.Thread(target=bar,args=(5,)) t2.setDaemon(True) # 主线程结束不等待子线程 t2.start() t1.join() # 加入主线程阻塞 # t2.join() print(‘ending!‘) print(‘cost time:‘,time.time()-s)
线程的类继承式创建
import threading import time class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) # super().__init__() def run(self): print(‘OK‘) time.sleep(2) print(‘end t1‘) t1 = MyThread() t1.start() print(‘ending‘)
线程三把锁
互斥锁
import threading import time def sub(): global num lock.acquire() temp = num time.sleep(0.1) num = temp-1 lock.release() time.sleep(2) num = 100 lock = threading.Lock() l = [] for i in range(100): t = threading.Thread(target=sub,args=()) t.start() l.append(t) for t in l: t.join() print(num)
递归锁
import threading import time class MyThread(threading.Thread): def __init__(self): super().__init__() def run(self): self.foo() self.bar() def foo(self): RLock.acquire() print(‘I am %s GET LOCKA-----%s‘ %(self.name,time.ctime())) RLock.acquire() print(‘I am %s GET LOCKB-----%s‘ %(self.name,time.ctime())) RLock.release() # time.sleep(1) RLock.release() # time.sleep(1) def bar(self): RLock.acquire() print(‘I am %s GET LOCKA-----%s‘ %(self.name,time.ctime())) # time.sleep(1) RLock.acquire() print(‘I am %s GET LOCKB-----%s‘ %(self.name,time.ctime())) RLock.release() # time.sleep(2) RLock.release() RLock = threading.RLock() # LockB = threading.Lock() for i in range(10): t = MyThread() t.start()
信号量
import threading import time semaphore = threading.Semaphore(10) def foo(): semaphore.acquire() print(‘OK‘) time.sleep(1) semaphore.release() for i in range(100): t = threading.Thread(target=foo,args=()) t.start()
event对象
import threading,time event = threading.Event() # 默认isSet()=False,加.wait()阻塞 def foo(): while not event.is_set(): print(‘wait.....‘) event.wait(2) print(‘Connect to redis server‘) for i in range(5): t = threading.Thread(target=foo,args=()) t.start() print(‘attempt to start redis server‘) time.sleep(10) event.set() # 主线程给子线程set()
队列
队列:基于锁实现的,用于多线程,保证线程安全的一种数据结构
############################################ FIFO先进先出模型 import queue q = queue.Queue(3) # 参数为队列最大数,不加参数默认无限大 print(q) q.put(11) q.put(‘hello‘) # q.put(3.14) q.put(555,block = False) # 阻塞,如果队列满,报错 # q.put(555) # 大于最大值,会阻塞,等待队列中数据被拿走后在进队列 print(q.get()) print(q.get()) print(q.get()) # print(q.get(block = False)) # 阻塞,如果队空,报错 # print(q.get()) # 队列空后,会阻塞,等待队列被加入
############################################ LIFO后进先出模型 import queue q = queue.LifoQueue() q.put(11) q.put(22) q.put(33) while not q.empty(): print(q.get())
############################################ priority优先级模型 import queue q = queue.PriorityQueue() q.put([1,‘11111‘]) # []表示一个序列数据类型,也可全部换成() q.put([1,‘00000‘]) # 优先级相同,优先级按照ascii码顺序 q.put([5,‘55555‘]) q.put([3,‘33333‘]) q.put([4,‘44444‘]) q.put([2,‘22222‘]) while not q.empty(): print(q.get())
队列的两个方法.join()和.task_done()
两个方法必须配合使用
.join()方法阻塞进程,知道所有任务完成
.task_done()方法在每次队列执行完后必须添加
import queue,threading q = queue.Queue() def foo(): q.put(111) q.put(222) q.put(333) q.join() print(‘ok‘) def bar(): print(q.get()) q.task_done() # 每取一个队列,必须执行一条task_done() print(q.get()) q.task_done() print(q.get()) q.task_done() t1 = threading.Thread(target=foo,args=()) t1.start() t2 = threading.Thread(target=bar,args=()) t2.start()
‘‘‘队列实例:生产者消费者模型生产者:创建数据的模型消费者:获取数据的模型 优点: 1、解耦合 2、实现并发‘‘‘
import queue,threading,time import random q=queue.Queue(50) def Producer(id): count=1 while count<10: # 一次可做10个包子 if q.qsize()<20: # 当包子数小于20个,厨师才做 s=random.randint(1,100) # 包子代号 q.put(s) print(id+" has made baozi %s"%s) time.sleep(1) # 此IO可切线程,每做一个包子换另一个厨师,直到做够最小包子数 count+=1 def Consumer(id): while True: s=q.get() # 取包子,s是代号 print("Consumer "+id+" has eat %s"%s) time.sleep(2) for i in range(10): t1=threading.Thread(target=Producer,args=(str(i),)) t1.start() for i in range(10): t=threading.Thread(target=Consumer,args=(str(i),)) t.start()
时间: 2024-08-17 13:37:01