日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Day28:Event对象、队列、multiprocessing模块

發(fā)布時(shí)間:2025/4/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Day28:Event对象、队列、multiprocessing模块 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、Event對(duì)象

  線程的一個(gè)關(guān)鍵特性是每個(gè)線程都是獨(dú)立運(yùn)行且狀態(tài)不可預(yù)測。如果程序中的其他線程需要通過判斷某個(gè)線程的狀態(tài)來確定自己下一步的操作,這時(shí)線程同步問題就 會(huì)變得非常棘手。為了解決這些問題,我們需要使用threading庫中的Event對(duì)象。 對(duì)象包含一個(gè)可由線程設(shè)置的信號(hào)標(biāo)志,它允許線程等待某些事件的發(fā)生。在初始情況下,Event對(duì)象中的信號(hào)標(biāo)志被設(shè)置為假。如果有線程等待一個(gè)Event對(duì)象,而這個(gè)Event對(duì)象的標(biāo)志為假,那么這個(gè)線程將會(huì)被一直阻塞直至該標(biāo)志為真。一個(gè)線程如果將一個(gè)Event對(duì)象的信號(hào)標(biāo)志設(shè)置為真,它將喚醒所有等待這個(gè)Event對(duì)象的線程。如果一個(gè)線程等待一個(gè)已經(jīng)被設(shè)置為真的Event對(duì)象,那么它將忽略這個(gè)事件,繼續(xù)執(zhí)行。

event.isSet(): 返回event的狀態(tài)值True或者False;event.wait(): 如果 event.isSet()==False將阻塞線程;event.set(): 設(shè)置event的狀態(tài)值為True,所有阻塞池的線程激活進(jìn)入就緒狀態(tài), 等待操作系統(tǒng)調(diào)度;event.clear(): 恢復(fù)event的狀態(tài)值為False。

可以考慮一種應(yīng)用場景(僅僅作為說明),例如,我們有多個(gè)線程從Redis隊(duì)列中讀取數(shù)據(jù)來處理,這些線程都要嘗試去連接Redis的服務(wù),一般情況下,如果Redis連接不成功,在各個(gè)線程的代碼中,都會(huì)去嘗試重新連接。如果我們想要在啟動(dòng)時(shí)確保Redis服務(wù)正常,才讓那些工作線程去連接Redis服務(wù)器,那么我們就可以采用threading.Event機(jī)制來協(xié)調(diào)各個(gè)工作線程的連接操作:主線程中會(huì)去嘗試連接Redis服務(wù),如果正常的話,觸發(fā)事件,各工作線程會(huì)嘗試連接Redis服務(wù)。

import threading,timeevent = threading.Event()def foo():while not event.is_set():print('wait....')event.wait()print('Connect to redis server')print('attempt to start redis server')for i in range(5):t = threading.Thread(target=foo)t.start()time.sleep(10) event.set()''' 運(yùn)行結(jié)果: attempt to start redis server wait.... wait.... wait.... wait.... wait.... Connect to redis server Connect to redis server Connect to redis server Connect to redis server Connect to redis server''' import threading,time,logginglogging.basicConfig(level=logging.DEBUG,format='%(threadName)-10s %(message)s')def worker(event):logging.debug('Waiting for redis ready...')event.wait()logging.debug('redis ready,and connect to redis server and do some work [%s]',time.ctime())time.sleep(1)def main():readis_ready=threading.Event()t1=threading.Thread(target=worker,args=(readis_ready,),name='t1')t1.start()t2=threading.Thread(target=worker,args=(readis_ready,),name='t2')t2.start()logging.debug('first of all,check redis server,make sure it is OK,and then trigger the redis ready event')time.sleep(3)readis_ready.set()if __name__=='__main__':main() View Code

threading.Event的wait方法還接受一個(gè)超時(shí)參數(shù),默認(rèn)情況下如果事件一致沒有發(fā)生,wait方法會(huì)一直阻塞下去,而加入這個(gè)超時(shí)參數(shù)之后,如果阻塞時(shí)間超過這個(gè)參數(shù)設(shè)定的值之后,wait方法會(huì)返回。對(duì)應(yīng)于上面的應(yīng)用場景,如果Redis服務(wù)器一致沒有啟動(dòng),我們希望子線程能夠打印一些日志來不斷地提醒我們當(dāng)前沒有一個(gè)可以連接的Redis服務(wù),我們就可以通過設(shè)置這個(gè)超時(shí)參數(shù)來達(dá)成這樣的目的:

import threading,timeevent = threading.Event()def foo():while not event.is_set():print('wait....')event.wait(2)print('Connect to redis server')print('attempt to start redis server')for i in range(2):t = threading.Thread(target=foo)t.start()time.sleep(5) event.set() ''' 運(yùn)行結(jié)果: attempt to start redis server wait.... wait.... wait.... wait.... wait.... wait.... Connect to redis server Connect to redis server ''' def worker(event):while not event.is_set():logging.debug('Waiting for redis ready...')event.wait(2)logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())time.sleep(1)

這樣,我們就可以在等待Redis服務(wù)啟動(dòng)的同時(shí),看到工作線程里正在等待的情況。

二、隊(duì)列(queue)

queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.

1、get與put方法

''' 創(chuàng)建一個(gè)“隊(duì)列”對(duì)象import queue q = queue.Queue(maxsize = 10) queue.Queue類即是一個(gè)隊(duì)列的同步實(shí)現(xiàn)。隊(duì)列長度可為無限或者有限??赏ㄟ^Queue的構(gòu)造函數(shù)的可選參數(shù) maxsize來設(shè)定隊(duì)列長度。如果maxsize小于1就表示隊(duì)列長度無限。將一個(gè)值放入隊(duì)列中 q.put(10) 調(diào)用隊(duì)列對(duì)象的put()方法在隊(duì)尾插入一個(gè)項(xiàng)目。put()有兩個(gè)參數(shù),第一個(gè)item為必需的,為插入項(xiàng)目的值;第二個(gè)block為可選參數(shù),默認(rèn)為1。如果隊(duì)列當(dāng)前為空且block為1,put()方法就使調(diào)用線程暫停,直到空出一個(gè)數(shù)據(jù)單元。如果block為0,put方法將引發(fā)Full異常。將一個(gè)值從隊(duì)列中取出 q.get() 調(diào)用隊(duì)列對(duì)象的get()方法從隊(duì)頭刪除并返回一個(gè)項(xiàng)目。可選參數(shù)為block,默認(rèn)為True。如果隊(duì)列為空且block為True,get()就使調(diào)用線程暫停,直至有項(xiàng)目可用。如果隊(duì)列為空且block為False,隊(duì)列將引發(fā)Empty異常。''' View Code import queue q = queue.Queue(3)q.put(11) q.put('hello') q.put(3.123)print(q.get()) print(q.get()) print(q.get()) ''' 運(yùn)行結(jié)果: 11 hello 3.123 '''

2、join與task_done方法

''' join() 阻塞進(jìn)程,直到所有任務(wù)完成,需要配合另一個(gè)方法task_done。def join(self):with self.all_tasks_done:while self.unfinished_tasks:self.all_tasks_done.wait()task_done() 表示某個(gè)任務(wù)完成。每一條get語句后需要一條task_done。import queue q = queue.Queue(5) q.put(10) q.put(20) print(q.get()) q.task_done() print(q.get()) q.task_done()q.join()print("ending!") ''' import queue,threading q = queue.Queue(3) def foo():q.put(11)q.put('hello')q.put(3.123)q.join() def bar():print(q.get())q.task_done() #注釋掉本行,程序?qū)⒉粫?huì)結(jié)束。t1 = threading.Thread(target=foo) t1.start()for i in range(3):t = threading.Thread(target=bar)t.start() ''' 運(yùn)行結(jié)果: 11 hello 3.123 '''

3、其他常用方法

''' 此包中的常用方法(q = queue.Queue()):q.qsize() 返回隊(duì)列的大小 q.empty() 如果隊(duì)列為空,返回True,反之False q.full() 如果隊(duì)列滿了,返回True,反之False q.full 與 maxsize 大小對(duì)應(yīng) q.get([block[, timeout]]) 獲取隊(duì)列,timeout等待時(shí)間 q.get_nowait() 相當(dāng)q.get(False)非阻塞 q.put(item) 寫入隊(duì)列,timeout等待時(shí)間 q.put_nowait(item) 相當(dāng)q.put(item, False) q.task_done() 在完成一項(xiàng)工作之后,q.task_done() 函數(shù)向任務(wù)已經(jīng)完成的隊(duì)列發(fā)送一個(gè)信號(hào) q.join() 實(shí)際上意味著等到隊(duì)列為空,再執(zhí)行別的操作'''

4、其他模式

Python queue模塊有三種隊(duì)列及構(gòu)造函數(shù): 1、Python queue模塊的FIFO隊(duì)列先進(jìn)先出。 class queue.Queue(maxsize) 2、LIFO類似于堆棧,即先進(jìn)后出。 class queue.LifoQueue(maxsize) 3、還有一種是優(yōu)先級(jí)隊(duì)列級(jí)別越低越先出來。 class queue.PriorityQueue(maxsize) import queue #先進(jìn)后出q=queue.LifoQueue()q.put(34) q.put(56) q.put(12)print(q.get()) print(q.get()) print(q.get()) ''' 運(yùn)行結(jié)果: 12 56 34 ''' #優(yōu)先級(jí) q=queue.PriorityQueue() q.put([5,100]) q.put([7,200]) q.put([3,"hello"]) q.put([4,{"name":"alex"}])while 1:data=q.get()print(data)''' 運(yùn)行結(jié)果: [3, 'hello'] [4, {'name': 'alex'}] [5, 100] [7, 200] '''

5、生產(chǎn)者消費(fèi)者模型

在線程世界里,生產(chǎn)者就是生產(chǎn)數(shù)據(jù)的線程,消費(fèi)者就是消費(fèi)數(shù)據(jù)的線程。在多線程開發(fā)當(dāng)中,如果生產(chǎn)者處理速度很快,而消費(fèi)者處理速度很慢,那么生產(chǎn)者就必須等待消費(fèi)者處理完,才能繼續(xù)生產(chǎn)數(shù)據(jù)。同樣的道理,如果消費(fèi)者的處理能力大于生產(chǎn)者,那么消費(fèi)者就必須等待生產(chǎn)者。為了解決這個(gè)問題于是引入了生產(chǎn)者和消費(fèi)者模式。

生產(chǎn)者消費(fèi)者模式是通過一個(gè)容器來解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問題。生產(chǎn)者和消費(fèi)者彼此之間不直接通訊,而通過阻塞隊(duì)列來進(jìn)行通訊,所以生產(chǎn)者生產(chǎn)完數(shù)據(jù)之后不用等待消費(fèi)者處理,直接扔給阻塞隊(duì)列,消費(fèi)者不找生產(chǎn)者要數(shù)據(jù),而是直接從阻塞隊(duì)列里取,阻塞隊(duì)列就相當(dāng)于一個(gè)緩沖區(qū),平衡了生產(chǎn)者和消費(fèi)者的處理能力。

這就像,在餐廳,廚師做好菜,不需要直接和客戶交流,而是交給前臺(tái),而客戶去飯菜也不需要不找廚師,直接去前臺(tái)領(lǐng)取即可,這也是一個(gè)解耦的過程。

?

import time,random import queue,threadingq = queue.Queue()def Producer(name):count = 0while count <10:print("making........")time.sleep(random.randrange(3))q.put(count)print('Producer %s has produced %s baozi..' %(name, count))count +=1print("ok......") def Consumer(name):count = 0while count <10:time.sleep(random.randrange(3))if not q.empty():data = q.get()print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))else:print("-----no baozi anymore----")count +=1p1 = threading.Thread(target=Producer, args=('A',)) c1 = threading.Thread(target=Consumer, args=('B',))p1.start() c1.start() ''' 運(yùn)行結(jié)果:making........ Producer A has produced 0 baozi.. ok...... making........ Consumer B has eat 0 baozi... Producer A has produced 1 baozi.. ok...... making........ Producer A has produced 2 baozi.. ok...... making........ Consumer B has eat 1 baozi... Producer A has produced 3 baozi.. ok...... making........ Consumer B has eat 2 baozi... Consumer B has eat 3 baozi... Producer A has produced 4 baozi.. ok...... making........ Producer A has produced 5 baozi.. ok...... making........ Consumer B has eat 4 baozi... Consumer B has eat 5 baozi... Producer A has produced 6 baozi.. ok...... making........ Producer A has produced 7 baozi.. ok...... making........ Producer A has produced 8 baozi.. ok...... making........ Consumer B has eat 6 baozi... Consumer B has eat 7 baozi... Producer A has produced 9 baozi.. ok...... Consumer B has eat 8 baozi... Consumer B has eat 9 baozi... ''' 運(yùn)行結(jié)果

三、multiprocessing模塊

Multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency,effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

由于GIL的存在,python中的多線程其實(shí)并不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進(jìn)程。

multiprocessing包是Python中的多進(jìn)程管理包。與threading.Thread類似,它可以利用multiprocessing.Process對(duì)象來創(chuàng)建一個(gè)進(jìn)程。該進(jìn)程可以運(yùn)行在Python程序內(nèi)部編寫的函數(shù)。該P(yáng)rocess對(duì)象與Thread對(duì)象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition類 (這些對(duì)象可以像多線程那樣,通過參數(shù)傳遞給各個(gè)進(jìn)程),用以同步進(jìn)程,其用法與threading包中的同名類一致。所以,multiprocessing的很大一部份與threading使用同一套API,只不過換到了多進(jìn)程的情境。

1、Python的進(jìn)程調(diào)用

# Process類調(diào)用 from multiprocessing import Process import time def f(name):print('hello', name,time.ctime())time.sleep(1)if __name__ == '__main__':p_list=[]for i in range(3):p = Process(target=f, args=('alvin:%s'%i,))p_list.append(p)p.start()for i in p_list:p.join()print('end') ''' 運(yùn)行結(jié)果: hello alvin:0 Wed Jul 19 16:06:40 2017 hello alvin:2 Wed Jul 19 16:06:40 2017 hello alvin:1 Wed Jul 19 16:06:40 2017 end ''' #繼承Process類調(diào)用 from multiprocessing import Process import timeclass MyProcess(Process):def __init__(self):super(MyProcess, self).__init__()# self.name = namedef run(self):print ('hello', self.name,time.ctime())time.sleep(1)if __name__ == '__main__':p_list=[]for i in range(3):p = MyProcess()p.start()p_list.append(p)for p in p_list:p.join()print('end')''' 運(yùn)行結(jié)果: hello MyProcess-3 Wed Jul 19 16:09:39 2017 hello MyProcess-1 Wed Jul 19 16:09:39 2017 hello MyProcess-2 Wed Jul 19 16:09:39 2017 end '''

2、process類

構(gòu)造方法:

Process([group [, target [, name [, args [, kwargs]]]]])

  group: 線程組,目前還沒有實(shí)現(xiàn),庫引用中提示必須是None;?
  target: 要執(zhí)行的方法;?
  name: 進(jìn)程名;?
  args/kwargs: 要傳入方法的參數(shù)。

實(shí)例方法:

  is_alive():返回進(jìn)程是否在運(yùn)行。

  join([timeout]):阻塞當(dāng)前上下文環(huán)境的進(jìn)程程,直到調(diào)用此方法的進(jìn)程終止或到達(dá)指定的timeout(可選參數(shù))。

  start():進(jìn)程準(zhǔn)備就緒,等待CPU調(diào)度

  run():strat()調(diào)用run方法,如果實(shí)例進(jìn)程時(shí)未制定傳入target,這star執(zhí)行t默認(rèn)run()方法。

  terminate():不管任務(wù)是否完成,立即停止工作進(jìn)程

屬性:

  daemon:和線程的setDeamon功能一樣

  name:進(jìn)程名字。

  pid:進(jìn)程號(hào)。

from multiprocessing import Process import os import time def info(name):print("name:",name)print('parent process:', os.getppid())print('process id:', os.getpid())print("------------------")time.sleep(1)if __name__ == '__main__':info('main process line')p1 = Process(target=info, args=('alvin',))p2 = Process(target=info, args=('egon',))p1.start()p2.start()p1.join()p2.join()print("ending") ''' 運(yùn)行結(jié)果: name: main process line parent process: 3400 process id: 1712 ------------------ name: alvin parent process: 1712 process id: 8428 ------------------ name: egon parent process: 1712 process id: 8212 ------------------ ending'''

3、進(jìn)程間通信

3.1 進(jìn)程隊(duì)列Queue

from multiprocessing import Process, Queuedef f(q,n):q.put(n*n+1)print("son process",id(q))if __name__ == '__main__':q = Queue() #如果使用線程間的隊(duì)列queue.Queue則無法運(yùn)行print("main process",id(q))for i in range(3):p = Process(target=f, args=(q,i))p.start()print(q.get())print(q.get())print(q.get()) ''' 運(yùn)行結(jié)果: main process 41655376 son process 45073408 1 son process 44942336 2 son process 44942392 5'''

3.2 管道(pipe)

The?Pipe()?function returns a pair of connection objects connected by a pipe which by default is duplex (two-way).

pipe()函數(shù)返回由管道連接的一對(duì)連接對(duì)象,該管道默認(rèn)是雙向的(雙向的)。

For example:

from multiprocessing import Process, Pipedef f(conn):conn.send([12, {"name": "yuan"}, 'hello'])response = conn.recv()print("response", response)conn.close()if __name__ == '__main__':parent_conn, child_conn = Pipe() #管道兩個(gè)對(duì)象p = Process(target=f, args=(child_conn,))p.start()print(parent_conn.recv()) parent_conn.send("兒子你好!")p.join() ''' 運(yùn)行結(jié)果: [12, {'name': 'yuan'}, 'hello'] response 兒子你好! '''

Pipe()返回的兩個(gè)連接對(duì)象代表管道的兩端。?每個(gè)連接對(duì)象都有send()和recv()方法(等等)。?請(qǐng)注意,如果兩個(gè)進(jìn)程(或線程)嘗試同時(shí)讀取或?qū)懭牍艿赖耐欢?#xff0c;管道中的數(shù)據(jù)可能會(huì)損壞

3.3 manager

Queue和pipe只是實(shí)現(xiàn)了數(shù)據(jù)交互,并沒實(shí)現(xiàn)數(shù)據(jù)共享,即一個(gè)進(jìn)程去更改另一個(gè)進(jìn)程的數(shù)據(jù)

A manager object returned by?Manager()?controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

manager()返回的manager對(duì)象控制一個(gè)保存Python對(duì)象的服務(wù)器進(jìn)程,并允許其他進(jìn)程使用代理來操作它們。

from multiprocessing import Process, Managerdef f(d, l, n):d[n] = nd["name"] ="alvin"l.append(n)#print("l",l)if __name__ == '__main__':with Manager() as manager:d = manager.dict()    #字典l = manager.list(range(5)) #列表print(d,'\n',l)p_list = []for i in range(10):p = Process(target=f, args=(d,l,i))p.start()p_list.append(p)for res in p_list:res.join()print(d)print(l)''' 運(yùn)行結(jié)果: {}   初始化的字典 [0, 1, 2, 3, 4]  初始化的列表 {3: 3, 'name': 'alvin', 0: 0, 2: 2, 7: 7, 5: 5, 4: 4, 1: 1, 6: 6, 8: 8, 9: 9} [0, 1, 2, 3, 4, 3, 0, 2, 7, 5, 4, 1, 6, 8, 9]

3.4 進(jìn)程池

進(jìn)程池內(nèi)部維護(hù)一個(gè)進(jìn)程序列,當(dāng)使用時(shí),則去進(jìn)程池中獲取一個(gè)進(jìn)程,如果進(jìn)程池序列中沒有可供使用的進(jìn)進(jìn)程,那么程序就會(huì)等待,直到進(jìn)程池中有可用進(jìn)程為止。

from multiprocessing import Pool import timedef foo(args):time.sleep(5)print(args)if __name__ == '__main__':p = Pool(5)for i in range(30):p.apply_async(func=foo, args= (i,))p.close() # 等子進(jìn)程執(zhí)行完畢后關(guān)閉進(jìn)程池# time.sleep(2)# p.terminate() # 立刻關(guān)閉進(jìn)程池p.join() # 沒有join會(huì)立即結(jié)束

進(jìn)程池中有以下幾個(gè)主要方法:

  • apply:從進(jìn)程池里取一個(gè)進(jìn)程并執(zhí)行
  • apply_async:apply的異步版本
  • terminate:立刻關(guān)閉線程池
  • join:主進(jìn)程等待所有子進(jìn)程執(zhí)行完畢,必須在close或terminate之后
  • close:等待所有進(jìn)程結(jié)束后,才關(guān)閉線程池
  • 四、課后作業(yè)

    1、設(shè)計(jì)五個(gè)線程,2個(gè)生產(chǎn)者3消費(fèi)者:一個(gè)生產(chǎn)者每秒鐘生產(chǎn)1一個(gè)產(chǎn)品放入隊(duì)列,一個(gè)生產(chǎn)者每秒鐘生產(chǎn)2個(gè)產(chǎn)品放入隊(duì)列。
    每個(gè)消費(fèi)者每秒鐘從隊(duì)列中消費(fèi)1-5之間的一個(gè)隨機(jī)數(shù)個(gè)產(chǎn)品。

    對(duì)于生產(chǎn)者:
    隊(duì)列多于10個(gè)時(shí),生產(chǎn)者等待,否則生產(chǎn)者繼續(xù)生產(chǎn);
    對(duì)于消費(fèi)者:
    隊(duì)列空時(shí),消費(fèi)者等待,隊(duì)列有產(chǎn)品時(shí),消費(fèi)者繼續(xù)消費(fèi)。
    每個(gè)產(chǎn)品有自己獨(dú)特的標(biāo)記。

    import threading,time,queue,randomclass Producer(threading.Thread):def __init__(self,name,i):super().__init__()self.name=nameself.i=idef run(self):while True:time.sleep(self.i)if q.qsize()<10:a=random.choice(['baozi','jianbing','doujiang'])+str(random.randint(1,10))q.put(a)print('%s produce %s current menu %s'%(self.name,a,q.queue))class Consumer(threading.Thread):def __init__(self,name,q):super().__init__()self.name=namedef run(self):while True:time.sleep(1)if not q.empty():for i in range(random.randint(1,5)):a=q.get()print('%s eat %s'%(self.name,a))if __name__ == '__main__':q = queue.Queue()p=Producer('egon0',1)p.start()p = Producer('egon1', 0.5)p.start()for i in range(3):c=Consumer('yuan%s'%i,q)c.start()參考答案 參考答案

    2、設(shè)計(jì)一個(gè)關(guān)于紅綠燈的線程,5個(gè)關(guān)于車的線程;

    對(duì)于車線程,每隔一個(gè)隨機(jī)秒數(shù),判斷紅綠燈的狀態(tài),是紅燈或者黃燈,打印waiting;是綠燈打印running。

    對(duì)于紅綠燈線程: 首先默認(rèn)是綠燈,做一個(gè)計(jì)數(shù)器,十秒前,每隔一秒打印“l(fā)ight green”;第十秒到第十三秒,每隔一秒打印“l(fā)ight yellow”,13秒到20秒, ‘light red’,20秒以后計(jì)數(shù)器清零。重新循環(huán)。

    知識(shí)點(diǎn):event對(duì)象(提示:event對(duì)象即紅綠燈,為true是即綠燈,false時(shí)為黃燈或者紅燈)

    import threading,random,timeevent=threading.Event() def traffic_lights():count=0lights=['green light','yellow light','red light']current_light=lights[0]while True:while count<10:print(current_light,9-count)count+=1time.sleep(1)else:current_light=lights[1]event.set()while count<13:print(current_light,12-count)count+=1time.sleep(1)else:current_light=lights[2]while count<20:print(current_light,19-count)count += 1time.sleep(1)if count == 20:count=0current_light=lights[0]event.clear()breakdef car(name):print(name,'starting...')while True:time.sleep(random.randint(1,4))if not event.is_set():print('%s is running'%name)else:print('%s is waiting'%name)if __name__ == '__main__':t=threading.Thread(target=traffic_lights)t.start()for i in range(5):c=threading.Thread(target=car,args=('car%s'%(i+1),))c.start()參考答案 參考答案

    ?

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/Vee-Wang/p/7214340.html

    總結(jié)

    以上是生活随笔為你收集整理的Day28:Event对象、队列、multiprocessing模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。