11.python并發入門(part5 event對象)

一、引入event。

每個線程,都是一個獨立運行的個體,并且每個線程的運行狀態是無法預測的。

如果一個程序中有很多個線程,程序的其他線程需要判斷某個線程的運行狀態,來確定自己下一步要執行哪些操作。

threading模塊中的event對象恰好能做到這一點,event對象包含了一個可以通過線程設置的一個信號標志位,它允許線程一直等待某些事件的發生。

在初始化默認的情況下,event對象中的信號標識被設置為“假”,如果這時,有一個線程等待這個event對象,而這個event對象的信號標志為“假”,那么這個線程就會被一直阻塞下去,直到這個event信號標志為“真”,所有等待這個event對象的線程才會被喚醒。

也就是說,一個線程如果等待的event對象中的信號標志位“真”,這個線程會忽略這個事件(event),繼續執行。


二、event對象的常用方法。

event.isSet():返回event的狀態值。

event.wait(): 當event對象內部的信號標識設置為“假”(False),所有等待這個event對象的線程將會全部被阻塞。


event.set():設置event對象內部的信號標識為“真”(True),所有等待這個event對象的線程將會被喚醒,等待操作系統的調度。


event.clear():恢復event的狀態值為False。


下面這個圖,能讓你清楚的明白event.wait和event.set之間的關系:


三、event使用示例。

我們來考慮下event對象的應用場景。

假如,在一個程序中,有多個線程需要到redis中來取數據,每個線程都要去嘗試著去連接redis服務器,一般情況下,redis如果連接不成功,在所有線程中都需要嘗試著去重新連接。

如果我們想要在程序啟動時,先要確保redis服務器工作正常,接著在讓其他工作的線程去連接redis服務器,當遇到這種需求的時候,使用event對象就是一個非常不錯的選擇。

我們可以使用event機制去讓各個工作的線程去做一個簡單的通信,主線程去連接redis服務器,如果連接到了,event對象內的信號標識改為真,其余工作的線程就會被喚醒。


示例:

#!/usr/local/bin/python2.7

# -*- coding:utf-8 -*-

import threading

import time

import logging

logging.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():

? ? redis_ready = threading.Event()

? ? t1 = threading.Thread(target=worker,args=(redis_ready,),name="threading-1")

? ? t1.start()

? ? t2 = threading.Thread(target=worker,args=(redis_ready,),name="threading-2")

? ? 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)

? ? redis_ready.set()

if __name__ == '__main__':

? ? main()


輸出結果:

(threading-1) waiting for redis ready....

(threading-2) waiting for redis ready....

(MainThread) first of all,check redis server, make sure it is ok , and then trigger the redis ready event

(threading-1) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017

(threading-2) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017


代碼分析:

在上面這段代碼中,一共開了三個線程,分別是threading-1和threading-2還有主線程,首先主線程運行了main()函數,產生了一個event對象,這個event對象信號的初始值是False,然后創建了threading-1和threading-2兩個線程并且運行,輸出一條日志first of all,check redis server, make sure it is ok , and then trigger the redis ready event后sleep 3秒,此時切換到了threading-1,threading-1首先執行了worker函數,輸出一次日志,然后執行event.wait方法,當這個event對象的信號標識為False時,threading-1就被阻塞住了,暫時無法執行woker函數后面的內容,當threading-1被阻塞住后,隨即切換到threading-2(為什么一定切換到threading-2呢?這是因為主線程還在sleep),threading-2此時也去執行woker函數,同樣先輸出一條日志waiting for redis ready....,當執行到event.wait時,這個event對象的信號標志位依舊為False,所以執行到這里的時候,threading-2也會被阻塞。

過了3秒后,MainThread主線程sleep結束,開始向下運行,執行了redis_ready.set()后,我們創建的那個名為redis_ready的event對象中的信號標志會變為True,當這event對象的信號標志變為True之后,之前阻塞的threading-1和threading-2都會被喚醒,繼續執行woker函數后面的代碼。

(threading-1) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017

(threading-2) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017


四、event對象的補充。

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


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)





本文轉自蘇浩智 51CTO博客,原文鏈接:http://blog.51cto.com/suhaozhi/1925428,如需轉載請自行聯系原作者


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540191.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540191.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540191.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] Java 將字符串首字母轉為大寫 - 利用ASCII碼偏移

參考鏈接: 使用ASCII值檢查Java中的字符串是否僅包含字母 將字符串name 轉化為首字母大寫。普遍的做法是用subString()取第一個字母轉成大寫再與之后的拼接: str str.substring(0, 1).toUpperCase() str.substring(1); 看到一種效率更高的做法&…

俞永福卸任阿里大文娛董事長,改任 eWTP 投資組長

兩天前(11月13日),阿里文娛董事長俞永福離職的消息,在互聯網圈炸了鍋。但很快,俞本人就在微博做了澄清,并稱“永遠幸福,我不會離開”。然而就在今天(11月15日)&#xff0…

[轉載] java提取字符串中的字母數字

參考鏈接&#xff1a; 使用Regex檢查字符串在Java中是否僅包含字母 String str "adsf adS DFASFSADF阿德斯防守對方asdfsadf37《&#xff1f;&#xff1a;&#xff1f;%#&#xffe5;%#&#xffe5;%#$%#$%^><?1234"; str str.replaceAll("[^a-zA-…

snort的詳細配置

前一段一直在做snort入侵檢測系統的安裝以及配置&#xff0c;看了很多的網上資料&#xff0c;也算是總結了下前輩的經驗吧。需要的軟件包&#xff1a;1、httpd-2.2.6.tar.gz2、mysql-5.1.22-rc-linux-i686-icc-glibc23.tar.gz3、php-5.2.4.tar.bz24、acid-0.9.6b23.tar.gz5、ad…

[轉載] Java:獲取數組中的子數組的多種方法

參考鏈接&#xff1a; Java中的數組Array 我的個人博客&#xff1a;zhang0peter的個人博客 Java&#xff1a;從一個數組中創建子數組 使用Arrays.copyOfRange函數 Arrays.copyOfRange支持&#xff1a;boolean[]&#xff0c; byte[] &#xff0c;char[]&#xff0c;double…

[轉載] Java中Array(數組)轉List(集合類)的幾種方法

參考鏈接&#xff1a; Java中的數組類Array 1、循環。新建List類&#xff0c;循環填充。 2、利用Arrays類的靜態方法asList()。 Arrays.asList(T[])返回Arrays類的一個內部內List(T)&#xff0c;此類繼承自AbstractList&#xff0c;不可增刪。若想要一個可以增刪的List類&am…

Linux查看系統cpu個數、核心書、線程數

Linux查看系統cpu個數、核心書、線程數 現在cpu核心數、線程數越來越高&#xff0c;本文將帶你了解如何確定一臺服務器有多少個cpu、每個cpu有幾個核心、每個核心有幾個線程。 查看物理cpu個數 cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l 查看核…

[轉載] java中數組的反射的探究

參考鏈接&#xff1a; Java中的反射數組類reflect.Array 數組的反射有什么用呢&#xff1f;何時需要使用數組的反射呢&#xff1f;先來看下下面的代碼&#xff1a; Integer[] nums {1, 2, 3, 4}; Object[] objs nums; //這里能自動的將Integer[]轉成Object[] Object obj n…

防火墻iptables之常用腳本

防火墻iptables之常用腳本 轉自&#xff1a;http://zhujiangtao.blog.51cto.com/6387416/1286490 標簽&#xff1a;防火墻 主機 1。不允許別人ping我的主機&#xff0c;但是我可以ping別人的主機 #!/bin/bash iptables -F iptables -X iptables -Z modprobe ip_tables modprobe…

[轉載] java中50個關鍵字以及各自用法大全

參考鏈接&#xff1a; Java中的默認數組值 關鍵字和保留字的區別 正確識別java語言的關鍵字&#xff08;keyword&#xff09;和保留字&#xff08;reserved word&#xff09;是十分重要的。Java的關鍵字對java的編譯器有特殊的意義&#xff0c;他們用來表示一種數據類型&…

NFS 共享存儲

服務器客戶端yum -y install rpcbind nfs-utils 服務器 vim /etc/exports /data 192.168.10.0/24(rw,sync,no_root_squash) * ro # 只讀權限 * rw # 讀寫權限 * sync # 同步&#xff0c;數據更安全&#xff0c;速度慢 * async #異步&#xff0c;速度快&#xff0c;效率高&a…

[轉載] Java中的final變量、final方法和final類

參考鏈接&#xff1a; Java中的final數組 &#xff5c; Final arrays 1、final變量 final關鍵字可用于變量聲明&#xff0c;一旦該變量被設定&#xff0c;就不可以再改變該變量的值。通常&#xff0c;由final定義的變量為常量。例如&#xff0c;在類中定義PI值&#xff0c;可…

Linux基礎篇_01_計算機概論

學習資料&#xff1a;《鳥哥的Linux私房菜&#xff08;基礎篇&#xff09;》部分&#xff1a;Linux的規劃與安裝 時間&#xff1a;20130225 學習筆記&#xff1a;計算機定義&#xff1a;接受使用者輸入指令與數據&#xff0c; 經由中央處理器的數學與邏輯單元運算處理后&#x…

[轉載] java中的經典問題:傳值與傳引用

參考鏈接&#xff1a; 有關Java中數組分配的有趣事實 參數傳遞的秘密 知道方法參數如何傳遞嗎&#xff1f; 記得剛開始學編程那會兒&#xff0c;老師教導&#xff0c;所謂參數&#xff0c;有形式參數和實際參數之分&#xff0c;參數列表中寫的那些東西都叫形式參數&#x…

[3/21]Windows Server 2008時鐘方面的改進展示

在Windows Server 2008中的時鐘顯示和以往Windows Server 2003及以前的版本顯示有很大的差別。如果要顯示并進行簡單的時間修改可以在時鐘上雙擊&#xff0c;會出現如下圖所示的界面。在上圖中可以調整但無法進行真正的修改&#xff0c;徹底修改需要點擊&#xff02;更改日期和…

[轉載] 黑馬程序員_學習筆記8_C#基礎歸納之數組

參考鏈接&#xff1a; Java中的鋸齒數組Jagged array ---------------------- Windows Phone 7手機開發、.Net培訓、期待與您交流&#xff01; ---------------------- 什么是數組&#xff1f; 數組是一組數據結構&#xff0c;它可以包含同一類型的多個元素。C#用特殊記號還…

2Python全棧之路系列之MysQl基本數據類型

Python全棧之路系列之MySQL基本數據類型 MySQL中定義數據字段的類型對你數據庫的優化是非常重要的。 MySQL支持多種類型&#xff0c;大致可以分為三類&#xff1a; 數字類型 日期和時間類型 字符串類型 數字類型 類型大小用途BIT-二進制TINYINT1字節小整數值INT or INTEGER4字…

[轉載] JAVA筆記_(Day04,Day05)函數數組

參考鏈接&#xff1a; 了解Java中的數組IndexOutofbounds異常 文章目錄 函數定義練習誤區重載&#xff08;overload&#xff09;重載選擇題練習函數的內存調用問題 數組定義數組的內存圖解數組的常見問題應用求和最大值將數組轉成字符串查表法轉十六進制查表版&#xff08;十六…

VDI序曲二 RemotoAPP部署

首先&#xff0c;我們需要準備如下角色&#xff1a;沿用VDI序曲一的2臺物理服務器以及角色我們在物理服務器1的hyper-v上&#xff0c;我們利用之前我介紹的“服務器虛擬化之準備母盤VHD”的方法再創建如下虛擬機&#xff1a;WIN-RDAPP&#xff1b;WIN-RDWA&#xff1b;WIN-RDCB…

[轉載] Java ArrayList toArray(T[] a) 解惑

參考鏈接&#xff1a; Java中的Array vs ArrayList 先看一個小的代碼片段 ArrayList<Integer> arrayList new ArrayList<>(); Collections.addAll(arrayList, 11, 21, 31, 41, 51); Integer[] a new Integer[0]; Integer[] b new Integer[arrayList.size()]; …