当前位置: 首页 > news >正文

永州城乡建设网站wordpress作伪静态网页404

永州城乡建设网站,wordpress作伪静态网页404,深圳seo优化公司哪家好,给女朋友做网站python学习——多线程概念python中线程的开发线程的启动线程的退出和传参threading的属性和方法threading实例的属性和方法多线程daemon线程和non-demone线程daemon线程的应用场景线程的jointhreading.local类线程的延迟执行#xff1a;Timer线程同步Event 事件Lock ——锁加锁… python学习——多线程概念python中线程的开发线程的启动线程的退出和传参threading的属性和方法threading实例的属性和方法多线程daemon线程和non-demone线程daemon线程的应用场景线程的jointhreading.local类线程的延迟执行Timer线程同步Event 事件Lock ——锁加锁和解锁锁的应用场景非阻塞锁可重入的锁RlockConditionBarrier ——栅栏/屏障Barrier的应用Semaphone信号量概念 并行(parallel)同时做某些事情可以互不干扰的同一时刻做几件事 例如跑在道路上不同车道上的汽车一条车道一辆车 并行(concurrenty):同事做某些事情但是强调同一个时段做几件事情 例如十字路口的红绿灯每个方向有10min的通行时间不同方向的车辆交替行驶实现不同方向的通行 如果要处理的任务过多处理机器较少就需要将各个任务排成一个队列按照一定的顺序解决例如先进先出缓冲区就是排成的队列可以认为他是一个缓冲地带优先队列如果有紧急任务可以将紧急任务排在特殊的队列中优先解决特殊队列中的任务这个特殊队列就是优先队列争抢只有一个处理机他一次也只能处理一个任务一个任务占据处理机就视为锁定窗口多个任务挤着去占用处理机就是争抢的过程在任务未处理完之前不能处理其他任务这就是锁任务抢到处理机就上锁锁有排他性其他任务只能等待预处理一种提前加载用户需要的数据的思路这种方式缓存常用 例如食堂打饭80%的人喜欢的菜品提前做打完即走缩短窗口的锁定时间20%的人先做这样解决任务的速度就会块很多 水平扩展日常通过购买更多的服务器或者多开进程进程实现并行处理开解决并发问题的思想 计算机中单核CPU同事处理多个任务这不是并行是并发 垂直扩展提高任务的执行速度或者提高单个性能CPU的性能或者单个服务器安装更多的CPU的思想消息中间件常见的有RabbitMQ、ActiveMQ(Apache提供)、RecketMQ(阿里提供)、kafka(分布式服务Apache提供)等系统之外缓存消息队列的地方用于存放系统接受不了的消息提升消息的存储能力进程和线程之间的关系 线程是操作熊能够进行运算调度的最小单位 线程被包含在进程中是进程中实际运作的单位 一个程序执行的实例就是一个进程 进程是计算机中程序关于某数据集合上的一次运行活动是系统进行资源分配和调度的基本单位是操作系统的基础 程序被操作系统加载到内存中就是进程进程存放的指令和数据资源他是线程的容器 线程是轻量级的进程是程序执行的最小单元 一个进程可以对应多个线程线程可以认为是进程的父类线程可以共享进程的资源 python中进程会启动一个解释器进程里面至少有一个线程这个线程就是主线程。不同进程之间是不可以随便交互数据的 python中线程的开发 python中线程开发使用标准库threading线程的区分是靠线程id的不是靠名字的其原始代码中有如下部分 def __init__(self, groupNone, targetNone, nameNone,args(), kwargsNone, *, daemonNone):以上代码中 target表示线程调用的对象也就是目标函数 name为线程起的名字 args为目标函数传递的实参类型是元祖 kwargs为目标函数传递的关键词参数目标是字典、 线程的启动 import threading # 加载线程库 import timedef worker():# 自定义线程函数,启动线程后要调用的方法for i in range(0,9):time.sleep(1)print(welcome to study python)def worker_1():# 自定义线程函数,启动线程后要调用的方法for i in range(0,9):time.sleep(1)print(welcome to study threading……)t threading.Thread(targetworker) # 对线程库中的类进行实例化指定线程调用的函数 t.start() #启动线程,线程启动之后不杀死线程的情况下 # 要将目标函数执行完才能结束t threading.Thread(targetworker_1) t.start() # 并发运行有两个函数启动两个线程代码解析 通过threading.Thread创建一个线程对象target是目标函数 线程启动调用start方法 并发调用多个函数就需要启动两个线程分别对应不同的函数已达到并发的效果 线程的退出和传参 python中没有提供线程退出的方法线程会在下面情况下退出 线程函数内语句执行完毕 线程函数中抛出未处理的异常 python中的线程没有优先级没有线程组的概念也不能被销毁停止挂起因此也就没有恢复和中断线程的传参和函数的传参没有区别其本质上就是函数传参实参传元祖关键字参数传字典 threading的属性和方法 current_thread返回当前线程的对象main_thread返回主线程的对象active_count当前处于alive状态的线程个数enumerate返回所有或者的线程列表 包括已经终止的线程和未开始的线程 get_ident返回当前线程的ID非0 整数 import threading # 加载线程库 import timedef worker():# 自定义线程函数,启动线程后要调用的方法for i in range(0,3):time.sleep(1)print(welcome to study python)print(threading.current_thread()) print(threading.active_count()) print(threading.enumerate()) print(threading.get_ident()) t threading.Thread(targetworker) t.start() # 并发运行有两个函数启动两个线程threading实例的属性和方法 线程的name只是一个名称可以重复但是ID必须唯一不过ID可以在退出线程之后再利用name只是线程的一个名字或者可以理解为一个标识ident线程ID是一个非0 整数 线程启动之后才会有ID否则为None 线程退出之后ID依旧可以访问 ID可以重复利用 is_alive返回线程是否活着是一个布尔值start启动线程每一个线程必须且只能执行该方法一次run运行线程函数使用start方法启动线程是启动了一个新的线程但是使用run方法并没有启动新的线程就是在主线程中调用了一个普通的函数因此启动线程需要使用start方法可以启动多个线程 import threading # 加载线程库 import timedef worker():# 自定义线程函数,启动线程后要调用的方法for i in range(0,3):time.sleep(1)print(welcome to study python)t threading.Thread(targetworker) t.start() # 并发运行有两个函数启动两个线程print(t.name) print(t.ident) print(t.is_alive())print(time.sleep(10))print(t.name) print(t.ident) print(t.is_alive())**********************run_result******************* Thread-1 14664 True welcome to study python welcome to study python welcome to study python None Thread-1 14664 False多线程 多线程就是一个进程中有多个线程实现一种并发没有开新的线程就是一个普通的函数调用执行完t2.run()就执行t1.run()这里不是多线程当使用start方法启动线程之后进程内有多个线程并行的工作这就是多线程一个进程中至少有一个线程并作为程序的入口这个就是主线程一个进程至少有一个主进程其他线程成为工作线程 import threading # 加载线程库 import timedef worker():count 0# 自定义线程函数,启动线程后要调用的方法while True:if count 5:breaktime.sleep(0.5)count1print(worker running)print(threading.current_thread().name,threading.get_ident())class MyThread(threading.Thread):def start(self):print(~~~~~~~~~~~~~~)super().start()def running(self) :print(***************)super().run()t1 MyThread(nameworker1,targetworker) t2 MyThread(nameworker2,targetworker)t2.start() # 使用这种方法t1和t2返回的进程id是不一样的有两个进程 t1.start() #t2.run() # 使用这种方法t1和t2返回的进程id是一样的有一个进程 #t1.run()daemon线程和non-demone线程 主线程就是第一个启动的线程如果进程A中启动了一个进程BA就是B的父线程B就是A的子线程python中构建县城的时候可以设置daemon属性主线程是non-daemon线程即daemonfalse不写daemon属性不代表线程是主线程线程具有一个daemin属性可以设置为True或者False也可以不设置不设置时取值为None 如果daemin属性为False主线程执行完成之后会等待工作线程结束 但是daemon属性为True主线程执行完成之后就立即结束了不会等待工作线程 如果不设置daemin就取当前的daemin来设置从主线程创建的所有线程不设置daemin属性则默认daemonFalse也就是non-daemon线程再重复一遍python程序在没有活着的non-daemin线程运行时退出也就是剩下的只能是daemon县城主线程才能退出否则主线程只能等待 import threading # 加载线程库 import timedef fod():time.sleep(0.5)for i in range(10):print(i) # 主线程是non-daemon线程 t threading.Thread(targetfod,daemonFalse) # 当daemon为False时下面的print语句打印完毕之后即可结束 t.start()print(ending)***********************two******************** def fod(n):for i in range(n):print(i)time.sleep(0.5) # 主线程是non-daemon线程 t threading.Thread(targetfod,args(3,),daemonTrue) t.start()t threading.Thread(targetfod,args(5,),daemonFalse) t.start()time.sleep(2) print(ending)daemon线程的应用场景 后台任务例如发送心跳包监控这种场景最多主线程工作才有用的线程例如主线程中维护公共资源主线程已经清理了准备退出工作线程再使用这些资源就没有意义了一起退出最合适随时可以被终止的进程如果主线程退出需要其他工作线程一起退出就是用daemonTrue如果需要等待工作线程就需要daemonFalse或者下面的join方法 线程的join 可以理解为等待谁调用join谁等待join(timeoutvalue)是线程的标准方法之一一个线程A下例子中的主线程中调用另一个线程B下面例子中的darmon线程的join方法调用者A主线程将被阻塞直到被调用线程Bdaemon线程终止一个线程可以被join多次timeout参数指定调用者等待多久没有设置超时就一直等到被调用线程结束 import threading # 加载线程库 import timedef fod(n):for i in range(n):print(i)time.sleep(0.5) # 主线程是non-daemon线程 t threading.Thread(targetfod,args(3,),daemonTrue) t.start() t.join() #使用join方法之后只有daemon线程执行完毕主线程才能退出 # 不添加join的效果只有0和ending添加join之后可以全部打印print(ending)threading.local类 在Python中使用全局对象global虽然实现了全局作用域但是线程之间会相互干扰导致错误的结果python提供threading.local类将这个类的实例化得到一个全局对象但是不同的线程使用这个对象存储的数据其他线程看不到 import threading # 加载线程库 import timeglobal_data threading.local() # 创建实例实现线程之间的全局作用域,线程之间互不影响def worker():global_data.x 0 # 给实例创建一个x的属性for i in range(100):time.sleep(0.0001)global_data.x 1print(threading.current_thread(),global_data.x)for i in range(5):threading.Thread(targetworker).start() ***************************使用global实现会相互影响****************** x 0 def worker():global xfor i in range(100):time.sleep(0.0001)x 1print(threading.current_thread(),x)for i in range(5):threading.Thread(targetworker).start()线程的延迟执行Timer 作用定时器或者延迟执行threading.Timer继承自Thread,这个类用来定义多久执行一个函数threading.Timer(interval, function, args)),其中interval为等待时间function为执行函数args为方法传入的参数元组形式start方法执行之后Timer对象会处于等待状态等interval之后开始执行function的函数如果再执行函数之前的等待阶段使用了cancel方法就会跳过执行函数结束如果线程中的函数开始执行cancel就没有任何效果了总结Timer是Thread的子类是线程类具有线程的能力和特征(例如join方法可调用)他的实例水能够延时执行目标函数的线程在真正执行目标函数之前都可以cancel它再start之前调用cancel函数就是提前取消线程的启动 import threading import timedef add(x,y):print(xy)t threading.Timer(interval3, functionadd, args(2,4)) #等待3s后执行 t.start()time.sleep(0.5) t.cancel()#cancel是timer的新增方法非线程方法 # cancel放在start之前线程提前取消 # 继承线程终结存在这句话且等待时间小于timer等待时间add方法不执行线程同步 线程同步线程之间协同通过某种技术让一个线程访问这些数据时其他线程不能访问这些数据直到该线程完成对数据的操作解决多个线程/进程争抢同一个共享资源的问题线程同步存在临界区Critical Section、互斥量Mutex——这个可以理解为锁、信号量Semaphore和事件Event Event 事件 Event事件是指线程之间通信中最简单的实现使用一个内部的标记flag通过flag的True或者False的变化来进行操作其方法有 set()设置标记为True clear()设置标记为Flase is_set()标记是否为True询问当前状态 wait(timeoutNone)设置等待标记为True的时长None为无限等待等到返回True未等到超时就返回Flase 等待有wait也有sleep他们两者之间的关系是 wait优于sleep在多线程的时候wait会让出时间片其他线程也可以被调度但是sleep会一直占用时间片不会被让出 # 老板让员工生产10个杯子之后停止说good job from threading import Event,Thread import logging import timeFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)def boss(event:Event):logging.info(i am boss waittinng for you)event.wait() # 等待标识变为True执行下面的代码print(标识1, event.is_set()) # 判断当前线程的状态logging.info(Good Job)def Worker(event:Event,count 10):logging.info(i am working for you)cups []while 1:logging.info(make 1)time.sleep(0.5)cups.append(1)if len(cups) 10:print(标识2,event.is_set())# 判断当前线程的状态event.set()# 通知更改标识breaklogging.info(I finished my job,cups{}.format(cups))event Event() w Thread(targetWorker,args(event,)) b Thread(targetboss,args(event,)) w.start() b.start() **************run_result************ 2023-03-23 10:30:08,597-Thread-1-14700-i am working for you 2023-03-23 10:30:08,597-Thread-1-14700-make 1 2023-03-23 10:30:08,597-Thread-2-11076-i am boss waittinng for you 2023-03-23 10:30:09,120-Thread-1-14700-make 1 2023-03-23 10:30:09,630-Thread-1-14700-make 1 2023-03-23 10:30:10,143-Thread-1-14700-make 1 2023-03-23 10:30:10,648-Thread-1-14700-make 1 2023-03-23 10:30:11,160-Thread-1-14700-make 1 2023-03-23 10:30:11,666-Thread-1-14700-make 1 2023-03-23 10:30:12,172-Thread-1-14700-make 1 2023-03-23 10:30:12,679-Thread-1-14700-make 1 2023-03-23 10:30:13,192-Thread-1-14700-make 1 标识2 False 标识1 True 2023-03-23 10:30:13,706-Thread-1-14700-I finished my job,cups[1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 2023-03-23 10:30:13,706-Thread-2-11076-Good Job使用同一个Event对象标记Flag谁wait就是等到flag 变为True或者等到超时返回False不限制等待的个数 Lock ——锁 锁凡是存在共享资源争抢的地方都可以使用锁从而保证只有一个使用者可以完全使用这个资源原理一个线程再使用共享资源的时候要加锁防止别的线程使用使用完归还之后解锁让别的线程使用lock.acquire()默认阻塞 阻塞可以设置超时时间 非阻塞时timeout禁止设置 成功获取锁返回True否则就返回False lock.release()释放锁可以从任何线程调用释放 已上锁的锁会被重置为unlocked 未上锁的锁调用时抛出RuntimeError的异常 #老板等10个员工生产100个杯子 import logging import threadingFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)cups [] # 公共资源杯子的容器def worker(lock:threading.Lock,task100): #task, 杯子的个数while True:lock.acquire()#线程开始拿锁拿到锁就独占共享资源# 这个时候别人要使用共享的资源就只能等待count len(cups)# 每次计算杯子的个数logging.info(str(count))if count task:lock.release()# 如果这里直接退出其他的线程还在等待解锁# 会陷入死锁因此需要在退出之前解锁# 如果没有这句话run的时候就不会结束breakcups.append(1)# 没有进入循环说明自核条件添加元素lock.release()#解锁释放共享资源logging.info({} make 1.format(threading.current_thread().name))# 日志打印哪个线程添加的元素logging.info(cups:{}.format(len(cups)))lock threading.Lock() for i in range(10):threading.Thread(targetworker,args(lock,100)).start()加锁和解锁 一般来说加锁之后还要一些代码实现在释放之前还有可能抛出异常但是一旦出现异常锁是无法释放的但当前线程可能因为这个异常被终止这就产生了死锁加锁和解锁的常用语句 try……finally,使用这种方式保证出现异常时锁的释放 with上下文管理器锁对象支持上下文管理 例如以下代码逻辑上可能有问题但是语法没有问题 import threading from threading import Thread,Lock import timeclass Counter:def __init__(self):self._val 0self._lock Lock()def inc(self):# 方式一异常处理try:self._lock.acquire()#加锁self._val1finally:self._lock.release()#解锁def dec(self):try:self._lock.acquire() # 加锁self._val - 1finally:self._lock.release() # 解锁propertydef value(self):#方式二上下文管理器with self._lock:return self._valdef run_d(c:Counter,count100):for _ in range(count):for i in range(-50,50):if i0:c.dec()else:c.inc()cCounter() c110 c210000 for i in range(c1):threading.Thread(targetrun_d,args(c,c2)).start()# print(threading.current_thread().name)while 1:time.sleep(0.3)if threading.active_count() 1:print(threading.enumerate())print(c.value)else:print(threading.enumerate())break锁的应用场景 适用于访问和修改同一个共享资源的时候即读写同一个资源的时候如果全部都是读取同一个资源就不需要锁因为可以认为共享资源是不可变的每一次读取都是同一个值因此不需要加锁使用锁的注意事项 少用锁必要时用锁因为用了所多线程访问被锁的资源时就成了串行要么排队执行要么争抢执行例如告诉公路上的收费通道只有一个过这个路口必须排队但是过了这个路口可以并行通行 加锁的时间越短越好不需要应该立即释放一定要避免死锁 非阻塞锁 这种形式的锁在上锁之后不会阻止后面的进程再去拿这把锁也就是是说线程A拿到锁之后访问共享资源线程B在线程A没有执行完释放锁的情况下仍可以去访问共享资源因此可以结合if语句使用因为锁的返回值是布尔值 import logging import threading import timeFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)def worker(tasks):for task in tasks:time.sleep(0.2)if task.lock.acquire(False):# 获取到锁则返回True没有则是Falselogging.info({} {} begin to start.format(threading.current_thread(),task.name))time.sleep(3)task.lock.release()# 选取适当的时机释放锁else:logging.info({} {} begin to working.format(threading.current_thread(), task.name))class Task:def __init__(self,name):self.name nameself.lock threading.Lock()# 构造10个任务构造10个对象即10把锁 tasks [Task(task{}.format(x)) for x in range(10)]# 启动5个线程即启动5把锁一个线程已经拿到锁另外一个线程就拿不到了 # 就走worker中的else for i in range(5):threading.Thread(targetworker,nameworker{}.format(i),args(tasks,)).start()可重入的锁Rlock 可重入锁是线程相关的锁threading.local 和线程相关全局域线程S可以获得可重复锁并可以多次成功获取不会阻塞但是最后要在线程A中做和acquire次数相同的release使用可重入的锁不能跨线程 import threading def sub(l):l.release() # 报错不能跨线程lock threading.RLock() print(lock.acquire()) print(***************) print(lock.acquire(blockingFalse)) print(lock.acquire()) print(lock.acquire(timeout3.55)) print(lock.acquire(blockingFalse)) # print(lock.acquire(blockingFalse,timeout10)) # 会报异常 lock.release() lock.release() lock.release() lock.release() lock.release() # lock.release() # 对应异常的那个多了一次 print(*******************) print(lock.acquire()) # 主线程中的锁必须在主线程结束 threading.Thread(targetsub,args(lock,)).start()# 报错不能跨县城Condition 构造方法Condition(lockNone)可以传入一个lock或者Rlock的对象(锁对象)默认Rlockacquire() 和release()获得锁和取消锁wait(self,timeoutNone):等待或者超时notify(n1):唤醒之多执行数目个数的等待的线程没有等待的线程就不会任何操作notify_all()唤醒所有等待的线程Condition用于生产者或者消费者模型为了解决生产者和消费者速度不匹配的问题使用condition必须先acquire用完了要release因为内部使用了锁弄人使用Rliock锁最好的方式是使用上下文管理器消费者wait等待通知生产者生产信息对消费者发通知可以使用notify或者notify_all方法 import logging import time import randomFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)#暂时不来考虑线程安全只是为了演示contition的用法class DispatcherOne:def __init__(self,x0):self.data xself.event threading.Event()self.cond threading.Condition()def produce(self):# 生产者for i in range(10):data random.randint(1,100)with self.cond:self.data data # 随机生成的数据放置早初始化公共区域self.cond.notify_all() # 条件通知消费者生产好了唤醒线程logging.info(produce:{} {}.format(threading.current_thread().name, self.data))self.event.wait(1)self.event.set()def custom(self):#消费者#消费者先等待(wait)等生产者生产数据后通知等待就是线程阻塞while True:# 不断的接受生产者的数据就需要用到循环with self.cond:#上下文管理器#self.cond是构造方法本身就是锁出上下文之后就关闭self.cond.wait(3)# 线程等待阻止线程再次生产数据logging.info(custom:{} {}.format(threading.current_thread().name, self.data))#消费者消费数据 d DispatcherOne(1) p threading.Thread(targetd.produce) c threading.Thread(targetd.custom,daemonFalse) c.start() p.start()Barrier ——栅栏/屏障 此功能为python3.2之后引入的功能Barrier(parties, actionNone, timeoutNone)构建Barrier对象置顶参与方的数目 tiimeout是weait方法未指定超时的默认值 Barrier.n_waiting,当前在屏障中等待的线程数Barrier.parties,各方数就是需要多少个等待Barrier.wait(timeoutNone)等待通过屏障 返回0到线程数-1的整数每个线程返回不同 如果wait方法设置了超时并超时发送屏障将处于broken状态(打破状态) 从运行下面的代码可以得到所有的线程都在barrier.wait前等待直到达到参与者的数目屏障才会打开此时所有的线程停止等待继续执行 如果再有线程来还需要达到参与方的数目才能放行因此线程数是参与方的倍数 import logging import threadingFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)def worker(barrier:threading.Barrier):logging.info(wait for {} thread.format(barrier.n_waiting))# 屏障前输出当前有几个等待数try:barrier_id barrier.wait()#返回分配的每个线程的id每个线程都相同# 运行的时候可以看到在3个线程没有全部等待之前所有的线程都阻塞到这一块儿# 达到某种条件不等待之后全部的参与者参与进来之后下面的打印是线程抢着进行logging.info(after barrier {}.format(barrier_id))except threading.BrokenBarrierError:# 如果打破屏障就打印下面的信息logging.info(Broken Barrier)barrier threading.Barrier(3)#3为三个参与方for x in range(5):# 这里起大于参与者的线程如果起的线程个数非参与方的倍数线程会一直等待不会结束# 例如参与方3起了5个线程日志打印一轮后会在 barrier.wait()的地方阻塞两个线程threading.Event().wait(timeout2)threading.Thread(targetworker,nameworker-{}.format(x),args(barrier,)).start()Barrier.broken,如果屏障处于打破状态返回TrueBarrier.abort()将屏障处于broken的状态 等待中的线程或者调用等待方法的线程中都会抛出BrokenBarrierError的异常 直到reset方法来回复屏障 Barrier.reset()恢复屏障重新开始拦截Barrier中的wait方法如果超时屏障将处于broken状态就像执行了abort方法直到再次reset恢复屏障 import logging import threadingFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO)def worker(barrier:threading.Barrier):logging.info(wait for {} thread.format(barrier.n_waiting))try:barrier_id barrier.wait()#barrier_id barrier.wait(timeout0.5)#barrier的wait方法超时logging.info(after barrier {}.format(barrier_id))except threading.BrokenBarrierError:# 如果打破屏障就打印下面的信息logging.info(Broken Barrier)barrier threading.Barrier(3)#3为三个参与方for x in range(1,8):threading.Event().wait(timeout2)threading.Thread(targetworker,nameworker-{}.format(x),args(barrier,)).start()if x2:barrier.abort()# 手动打破异常会返回异常处理中的Broken Barrierlogging.info(当前线程状态{} .format(barrier.broken))# 打印屏障状态elif x4:barrier.reset()# 屏障恢复logging.info(当前线程状态{}.format(barrier.broken))Barrier的应用 并发初始化所有的线程都必须初始化之后才能继续工作例如运行前加载数据检查如果这些工作没有完成活着开始运行就不能正常工作或者一个功能需要10个线程完成10个步骤1个线程1个步骤才嫩个继续向下进行就需要先完成的等待其他线程完成步骤 Semaphone信号量 和lock很像信号量对象内部维护一个倒计数器每一次acquire都会-1当acquire方法发现技术为0时就阻塞请求线程直到其他的线程release后计数器大于0才会恢复阻塞的线程Semaphore(value1),构造方法value小鱼0就会抛出ValueError的异常Semaphore(value1).acquire(),获取信号量计数器减1获取成功则返回TrueSemaphore(value1).release()释放信号量计数器加1计数器永远不会低于0因为acquire的时候发现等于0就会阻塞使用Semaphone没有acquire直接release超过了约束值不会报错为了约束这种情况需要使用构造方法BoundedSemaphore BoundedSemaphore有界的信号量不允许使用release超出初始值的范围否则就会抛出ValueError的异常 # 可以跨线程 import logging import threadingFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO) def worker(s:threading.Semaphore):logging.info(in sub thread)logging.info(s.release())logging.info(sub thread over)#信号量 s threading.Semaphore(3) logging.info(s.acquire()) logging.info(s.acquire()) logging.info(s.acquire()) threading.Thread(targetworker,args(s,)).start()# 例子二 import logging import threadingFORMAT %(asctime)s-%(threadName)s-%(thread)d-%(message)s logging.basicConfig(formatFORMAT,levellogging.INFO) def worker(s:threading.Semaphore):logging.info(in sub thread)logging.info(s.acquire())logging.info(sub thread over)#信号量 s threading.Semaphore(3) logging.info(s.acquire()) logging.info(s.acquire()) logging.info(s.acquire()) threading.Thread(targetworker,args(s,)).start()print(…………………………) logging.info(s.acquire(False)) logging.info(s.acquire(timeout3))s.release()#释放信号量 print(end)
http://www.dnsts.com.cn/news/70211.html

相关文章:

  • 网站做不好一直不交付怎么办做一个微信小程序难吗
  • 建网站软件工具iis添加网站无法访问
  • 做平面设计什么素材网站好使网站建设 作用
  • 直播开放平台googleseo排名
  • 成都 网站建设培训作业提交免费网站
  • js网站效果广州网络推广公司费用
  • 网站推广工作内容分析网站建设流程
  • 东莞网站建设制作免费咨建设银行小微企业网站进不了
  • 网站开发asp 视频青岛网站建设哪家公司好
  • 做暧暧视频网站python如何开发小软件
  • 网站被黑了怎么恢复网页一般用什么软件制作
  • php mysql网站开发全程实例php 网站 发布
  • 泉州百度网站快速优化wordpress 图片预加载插件
  • 建网站的成本计算建立名词
  • 手机端网站设计静态网站什么意思
  • 做ptt有什么好的模板网站洞泾做网站
  • 方案图网站ui是做什么的
  • php网站开发 总结大学生跨境电商策划书范文
  • 比较好的企业网站asp个人网站下载
  • 惠州网站建设外包海外运营渠道的推广
  • 网站弹出广告的是怎么做的哈尔滨 网站建设仟路
  • 淄博张店做网站的公司免费注册帐号qq
  • 做网站挣钱吗现在网站建设什么最重要
  • 舒城县建设局网站首页2021年重大新闻事件
  • 基于php网站建设论文匿名聊天网站怎么做
  • 个人博客网站模板素材数据分析网站html模板下载
  • 挣钱做任务的网站做网站能改吗
  • 中小企业网站构建设计中国建设银行的网站
  • 网站做管理员消息推送html网站首页图片切换
  • 做网站哪里买空间好优秀简历模板