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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python模块整理(四):线程模块threading

發布時間:2024/4/11 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python模块整理(四):线程模块threading 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考網絡以及python書籍整理
一、Python threading三種調用方式介紹:
Thread 是threading模塊中最重要的類之一,可以使用它來創建線程。
第一種方式:創建一個threading.Thread()的實例對象,給它一個函數。在它的初始化函數(__init__)中將可調用對象作為參數傳入
第二種方式:創建一個threading.Thread的實例,傳給它一個可調用類對象,類中使用__call__()函數調用函數
第三種方式:是通過繼承Thread類,重寫它的run方法;
第一種和第三種常用。
實例可參考:http://tuoxie174.blog.51cto.com/1446064/442162
二、實際簡單使用
這里使用第三種方式:是通過繼承Thread類,重寫它的run方法
#下面的例子treadTest.py創建一個threading.Thread的一個子類KissThread,這子類KissThread重寫了超類threading.Thread的run方法
#使用時創建這個子類的實例對象。然后調用該實例的start()啟動run()函數
#run方法和start方法:它們都是從Thread繼承而來的,run()方法將在線程開啟后執行,可以把相關的邏輯寫到run方法中(通常把run方法稱
#為活動[Activity]);start()方法用于啟動線程。
#!/usr/bin/env python
import threading
import time
count=1

class KissThread(threading.Thread):
??????? def run(self):
??????????????? global count
??????????????? print "Thread # %s:Pretending to do stuff" % count
??????????????? count+=1
??????????????? time.sleep(2)
??????????????? print "done with stuff"


for t in range(5):
??????? KissThread().start()
??? ??? ??? ??? ???
#ping單線程實例??? common.py
#!/usr/bin/env python
import subprocess
import time

IP_LIST=['qq.com','163.com','sohu.com']
cmd_stub='ping -c 5 %s'

def do_ping(addr):
??????? print time.asctime(),"DOING PING FOR",addr
??????? cmd=cmd_stub % addr
??????? return subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)

z=[]
for ip in IP_LIST:
??????? p=do_ping(ip)??? #對象
??????? z.append((p,ip)) #將p這個對象和其產生對象的參數ip作為一個元組添加到列表中
???????
for p,ip in z:
??????? print time.asctime(),"WAITING PING FOR",ip
??????? p.wait()
??????? print time.asctime(),ip,"RETURN",p.returncode
三、線程化的ping掃描
這里使用第一種方式:創建一個threading.Thread()的實例對象,給它一個函數
創建一個threading.Thread()的實例,給它一個函數
參數group是預留的,用于將來擴展;
參數target是一個可調用對象(也稱為活動[activity]),在線程啟動后執行;
參數name是線程的名字。默認值為“Thread-N“,N是一個數字。
參數args和kwargs分別表示調用target時的參數列表和關鍵字參數。
#vim threadingping.py
#!/usr/bin/env python
import subprocess
from threading import Thread
from Queue import Queue

num_thread=3? #定義線程的數量
queue=Queue() #創建隊列實例
ips=['192.168.1.100','192.168.1.110','192.168.1.120','192.168.1.130','192.168.1.200']

def pinger(i,q):
??????? while True:
??????????????? ip=q.get() #獲取Queue隊列傳過來的ip,隊列使用隊列實例queue.put(ip)傳入ip,通過q.get() 獲得
??????????????? print "Thread %s:Pinging %s" %(i,ip)
??????????????? ret=subprocess.call("ping -c 1 %s" % ip,shell=True,stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
??? ??? ??? ??? #調用子進程執行命令,獲取退出狀態。不能使用subprocess.Popen也可以
??????????????? if ret==0:
??????????????????????? print "%s:is alive" % ip
??????????????? else:
??????????????????????? print "%s:did not respond" % ip
??????????????? q.task_done() #告訴queue.join()已完成隊列中提取元組的工作

for i in range(num_thread):#各線程開始工作
??????? worker=Thread(target=pinger,args=(i,queue)) #創建一個threading.Thread()的實例,給它一個函數以及函數的參數
??????? worker.setDaemon(True)??? #在start方法被調用之前如果沒有進行設置,程序會不定期掛起。
??????? worker.start() ??? #開始線程的工作,沒有設置程序會掛起,不會開始線程的工作,因為pinger程序是while True循環

for ip in ips:
??????? queue.put(ip)??? #將IP放入隊列中。函數中使用q.get(ip)獲取

print "Main Thread Waiting"
queue.join()??? #防止主線程在其他線程獲得機會完成隊列中任務之前從程序中退出。
print "Done"
?
四、多隊列和多線程池
# vim multhreading.py
#!/usr/bin/env python
import subprocess
import re
from threading import Thread
from Queue import Queue

num_ping_threads=3
num_arp_threads=3
in_queue=Queue()
out_queue=Queue()
ips=['192.168.1.100','192.168.1.110','192.168.1.120','192.168.1.130','192.168.1.200']

def pinger(i,iq,oq):
??????? while True:
??????????????? ip=iq.get()
??????????????? print "Thread %s:Pinging %s" %(i,ip)
??????????????? ret=subprocess.call("ping -c 1 %s" % ip,shell=True,stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
??????????????? if ret==0:
??????????????????????? #print "%s:is alive" % ip
??????????????????????? oq.put(ip) #將能ping通的ip吐給下另外一個隊列
??????????????? else:
??????????????????????? print "%s:did not respond" % ip
??????????????? iq.task_done()# 告訴iq.join()已完成隊列中提取元組的工

def arping(i,oq):
??????? while True:
??????????????? ip=oq.get() #從pinger函數中吐出的oq隊列里獲取IP
??????????????? p=subprocess.Popen("arping -c 1 %s" % ip,shell=True,stdout=subprocess.PIPE)
??? ??? ??? ??? #需要獲取子進程返回的內容,而不是簡單的退出狀態
??????????????? out=p.read()#返回的內容讀出來
??????????????? result=out.split()
??????????????? pattern=re.compile(":") #正則編譯匹配
??????????????? macaddr=None
??????????????? for item in result:
??????????????????????? if re.search(pattern,item):#查找到匹配的就賦值給macaddr
??????????????????????????????? macaddr=item
??????????????? print "IP Address:%s| Mac Address:%s" % (ip,macaddr)
??????????????? oq.task_done()# 告訴oq.join()已完成隊列中提取元組的工

for ip in ips:
??????? in_queue.put(ip)

for i in range(num_ping_threads):
??????? worker=Thread(target=pinger,args=(i,in_queue,out_queue)) #創建一個threading.Thread()的實例,給它一個函數以及函數的參數
??????? worker.setDaemon(True)??? #在start方法被調用之前如果沒有進行設置,程序會不定期掛起
??????? worker.start() ??? #開始線程的工作,沒有設置程序會掛起,不會開始線程的工作

for i in range(num_arp_threads):
??????? worker=Thread(target=arping,args=(i,out_queue))
??????? worker.setDaemon(True)
??????? worker.start()

print "Main Thread Waiting"
in_queue.join() #防止主線程在其他線程獲得機會完成隊列中任務之前從程序中退出。
out_queue.join()
print "Done"

五、使用threading.Timer線程延遲
Timer(延遲時間,函數)
threading.Timer是threading.Thread的子類,可以在指定時間間隔后執行某個操作。下面是Python手冊上提供的一個例子:
??? def hello():?
??????? print "hello, world"?
??? t = Timer(3, hello)?
??? t.start() # 3秒鐘之后執行hello函數
具體實例
# vim delay_threading.py
#!/usr/bin/env python
import sys
import time
import copy
from threading import Timer

if len(sys.argv)!=2:
??????? print "Must enter an interval"
??????? sys.exit(1)
???????
def hello():
??????? print "Hello,I just got called after a %s sec delay" % call_time
???????
delay=sys.argv[1]
call_time=copy.copy(delay) #copy是因為delay要倒計時遞減
t=Timer(int(delay),hello)
t.start()

print "waiting %s seconds to run function" % delay
for x in range(int(delay)):
??????? print "Main program is still running for %s more sec" % delay
??????? delay=int(delay)-1
??????? time.sleep(1)
語句有點混亂重新改寫過
# cp delay_threading.py delay_threading_new.py
#vim delay_threading_new.py
#!/usr/bin/env python
"""
USAGE:
??????? delay_threading_new.py intarg
"""

import sys
import time
import copy
from threading import Timer


def hello():
??????? print "Hello,I just got called after a %s sec delay" % call_time

if __name__=='__main__':
??????? if len(sys.argv)!=2:
??????????????? print __doc__
??????? else:
??????????????? try:
??????????????????????? delay=sys.argv[1]
??????????????????????? t=Timer(int(delay),hello)
??????????????????????? call_time=copy.copy(delay)
??????????????? except? ValueError:
??????????????????????? print __doc__
??????????????????????? sys.exit(1)
??????????????? else:
??????????????????????? t.start()
??????????????????????? print "waiting %s seconds to run function" % delay
??????????????????????? for x in range(int(delay)):
??????????????????????????????? print "Main program is still running for %s more sec" % delay
??????????????????????????????? delay=int(delay)-1
??????????????????????????????? time.sleep(1)
???????????
六、Thread類其他常用方法與屬性:
1、一般方法和屬性 【類Thread的方法】
Thread.getName()
Thread.setName()
Thread.name
用于獲取和設置線程的名稱。
Thread.ident
獲取線程的標識符。線程標識符是一個非零整數,只有在調用了start()方法之后該屬性才有效,否則它只返回None。
Thread.is_alive()
Thread.isAlive()
判斷線程是否是激活的(alive)。從調用start()方法啟動線程,到run()方法執行完畢或遇到未處理異常而中斷 這段時間內,線程是激活的。
Thread.join([timeout])
2、Thread.join 【類Thread的方法】
調用Thread.join將會使主調線程堵塞,直到被調用線程運行結束或超時。參數timeout是一個數值類型,表示超時時間,如果未提供該參數,那么主調線程將一直堵塞到被調線程結束。下面舉個例子說明join()的使用:
import threading, time?
def doWaiting():?
??? print 'start waiting:', time.strftime('%H:%M:%S')?
??? time.sleep(3)?
??? print 'stop waiting', time.strftime('%H:%M:%S')?
thread1 = threading.Thread(target = doWaiting)?
thread1.start()?
time.sleep(1)? #確保線程thread1已經啟動?
print 'start join'?
thread1.join()? #將一直堵塞,直到thread1運行結束。?
print 'end join'
???? ??? ???
3、鎖相關方法 【模塊threading的方法】
#使用隊列Queue就可以避免使用鎖的麻煩
threading.RLock和threading.Lock
在threading模塊中,定義兩種類型的瑣:threading.Lock和threading.RLock。它們之間有一點細微的區別,通過比較下面兩段代碼來說明:
import threading?
lock = threading.Lock() #Lock對象?
lock.acquire()?
lock.acquire()? #產生了死瑣。?
lock.release()?
lock.release()?

import threading?
rLock = threading.RLock()? #RLock對象?
rLock.acquire()?
rLock.acquire() #在同一線程內,程序不會堵塞。?
rLock.release()?
rLock.release()?

這兩種瑣的主要區別是:RLock允許在同一線程中被多次acquire。而Lock卻不允許這種情況。注意:如果使用RLock,那么acquire和release必須成對出現,即調用了n次acquire,必須調用n次的release才能真正釋放所占用的瑣。

4、threading.Condition 【模塊threading的方法】
threading.Condition
可以把Condiftion理解為一把高級的瑣,它提供了比Lock, RLock更高級的功能,允許我們能夠控制復雜的線程同步問題。threadiong.Condition在內部維護一個瑣對象(默認是RLock),可以在創建Condigtion對象的時候把瑣對象作為參數傳入。Condition也提供了acquire, release方法,其含義與瑣的acquire, release方法一致,其實它只是簡單的調用內部瑣對象的對應的方法而已。Condition還提供了如下方法(特別要注意:這些方法只有在占用瑣(acquire)之后才能調用,否則將會報RuntimeError異常。):
Condition.wait([timeout]):?
wait方法釋放內部所占用的瑣,同時線程被掛起,直至接收到通知被喚醒或超時(如果提供了timeout參數的話)。當線程被喚醒并重新占有瑣的時候,程序才會繼續執行下去。
Condition.notify():
喚醒一個掛起的線程(如果存在掛起的線程)。注意:notify()方法不會釋放所占用的瑣。
Condition.notify_all()
Condition.notifyAll()
喚醒所有掛起的線程(如果存在掛起的線程)。注意:這些方法不會釋放所占用的瑣。

5、threading.Event 【模塊threading的方法】
Event實現與Condition類似的功能,不過比Condition簡單一點。它通過維護內部的標識符來實現線程間的同步問題。(threading.Event和.NET中的System.Threading.ManualResetEvent類實現同樣的功能。)
Event.wait([timeout])
堵塞線程,直到Event對象內部標識位被設為True或超時(如果提供了參數timeout)。
Event.set()
將標識位設為Ture
Event.clear()
將標識伴設為False。
Event.isSet()
判斷標識位是否為Ture。

6、threading模塊其他方法:
threading.active_count()
threading.activeCount()
獲取當前活動的(alive)線程的個數。
threading.current_thread()
threading.currentThread()
?  獲取當前的線程對象(Thread object)。
threading.enumerate()
?  獲取當前所有活動線程的列表。
threading.settrace(func)
設置一個跟蹤函數,用于在run()執行之前被調用。
threading.setprofile(func)
設置一個跟蹤函數,用于在run()執行完畢之后調用。

參考:http://blog.csdn.net/JGood/article/details/4305604
參考:unix/linux python系統管理

轉載于:https://blog.51cto.com/ipseek/808818

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的Python模块整理(四):线程模块threading的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。