python threading_【python标准库学习】thread,threading(一)多线程的介绍和使用
在單個(gè)程序中我們經(jīng)常用多線程來處理不同的工作,尤其是有的工作需要等,那么我們會(huì)新建一個(gè)線程去等然后執(zhí)行某些操作,當(dāng)做完事后線程退出被回收。當(dāng)一個(gè)程序運(yùn)行時(shí),就會(huì)有一個(gè)進(jìn)程被系統(tǒng)所創(chuàng)建,同時(shí)也會(huì)有一個(gè)線程運(yùn)行,這個(gè)線程就是主線程main,在主線程中所創(chuàng)建的新的線程都是子線程,子線程通常都是做一些輔助的事。python中提供了thread和threading兩個(gè)模塊來支持多線程。這篇介紹一下python的多線程和基本使用,下一篇介紹python多線程同步問題。
python中使用線程有兩種方式,第一種是用thread模塊的start_new_thread函數(shù),另一種是用threading模塊的Thread類來包裝線程對(duì)象。
1.使用thread模塊
使用thread模塊的start_new_thread函數(shù)創(chuàng)建線程并啟動(dòng)。start_new_thread函數(shù)原型:
thread.start_new_thread(function, args[, kwargs])
>>> help(thread.start_new_thread)
Help on built-in function start_new_thread in module thread:
start_new_thread(...)
start_new_thread(function, args[, kwargs])
(start_new() is an obsolete synonym)
Start a new thread and return its identifier. The thread will call the
function with positional arguments from the tuple args and keyword arguments
taken from the optional dictionary kwargs. The thread exits when the
function returns; the return value is ignored. The thread will also exit
when the function raises an unhandled exception; a stack trace will be
printed unless the exception is SystemExit.
(END)
這個(gè)函數(shù)創(chuàng)建一個(gè)新線程,并立刻執(zhí)行函數(shù)function,args是該函數(shù)function的參數(shù),是一個(gè)元組,kwargs是可選的,它為函數(shù)提供了命名參數(shù)字典。該函數(shù)返回一個(gè)整數(shù),為線程標(biāo)示符。function函數(shù)執(zhí)行完后線程正常退出,如果執(zhí)行過程中有未處理的異常,線程會(huì)異常退出。
thread模塊的主要函數(shù):
1).start_new_thread()
創(chuàng)建并啟動(dòng)線程執(zhí)行function函數(shù),function執(zhí)行完線程退出,或者遇到未處理的異常線程異常退出。
2).thread.exit()
結(jié)束當(dāng)前線程,會(huì)觸發(fā)SystemExit異常,如果沒有捕獲處理該異常,線程會(huì)退出。
3).thread.get_ident()
得到該線程的標(biāo)示符,就是新建線程時(shí)返回的標(biāo)示符,是一個(gè)整數(shù)。
4).thread.interrupt_main
在主線程main中觸發(fā)一個(gè)KeyboardInterrupt異常,子線程用這個(gè)函數(shù)來終止主線程。
5).thread.allocate_lock()
創(chuàng)建一個(gè)鎖對(duì)象LockType,使多個(gè)線程同步訪問共享資源。
在python中使用多線程更多的是使用第二種方式,即使用threading模塊。
2.使用threading模塊
threading模塊是對(duì)thread模塊的第二次封裝,提供了更好的API來讓我們使用。使用threading實(shí)現(xiàn)多線程編程都是使用的Thread類,或者Timer類,Timer是Thread的子類,可以指定時(shí)間間隔后在執(zhí)行某個(gè)操作:
1 from threading importTimer2
3
4
5 defmain():6
7 print ‘timer test!‘
8
9 t = Timer(3, main)10
11 t.start()
使用Thread類有兩種方式,一種是直接創(chuàng)建Thread類的實(shí)例,另一種方式是自定義類來繼承Thread類。使用Thread類的實(shí)例,在它的初始化函數(shù)__init__中將可調(diào)用的對(duì)象作為參數(shù)傳入,Thread的初始化函數(shù)__init__原型:
__init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None);
group和verbose不知道是什么東西,target是可調(diào)用對(duì)象,線程啟動(dòng)后就執(zhí)行它,name為線程的名字,默認(rèn)為"Thread-N",N為數(shù)字,args和kwargs是調(diào)用target是的參數(shù)列表和關(guān)鍵字參數(shù)。
1 from threading importThread2
3 defmain(a, b):4
5 print ‘a(chǎn):%d, b:%d‘ %(a, b)6
7 Thread(target=main, name=‘newThread‘, args=(1, 2)).start()
自定義類來繼承Thread類,然后重寫run方法實(shí)現(xiàn)我們自己的操作。
from threading importThreadclassMyThread(Thread):def __init__(self, threadName, a, b):
Thread.__init__(self, name=threadName)
self.a=a
self.b=bdefrun(self):print ‘a(chǎn):%d, b:%d‘ %(self.a, self.b)
myThread= MyThread(‘newThread‘, 1, 2)
myThread.start()
邏輯代碼是寫在run方法中的,但是我們啟動(dòng)線程都是用的start方法,這兩個(gè)方法是有區(qū)別的,如果直接調(diào)用run()方法,只是單純的調(diào)用方法,而調(diào)用start()方法是將線程從新建狀態(tài)啟動(dòng)編程就緒狀態(tài),等待cpu的調(diào)度,這里涉及到線程的幾種狀態(tài),start()后線程沒有立即運(yùn)行而是編程就緒狀態(tài),當(dāng)?shù)玫絚pu時(shí)間片后編程運(yùn)行狀態(tài),當(dāng)run方法結(jié)束或者有未處理的異常,線程就結(jié)束變成死亡狀態(tài)等待被回收,在運(yùn)行狀態(tài)如果遇到資源沒有準(zhǔn)備好就會(huì)變成阻塞狀態(tài),當(dāng)?shù)玫劫Y源后再次編程就緒狀態(tài)等待cpu的調(diào)度。
threading模塊的主要類:
1).Thread類
上面已經(jīng)介紹。
2).Timer類
Thread的子類,上面已經(jīng)介紹。
3).Lock,RLock,Condition類
同步鎖,用于多實(shí)現(xiàn)線程同步,資源共享的問題。
4).Event類
用于多線程通信。
多線程同步鎖Lock,RLock,Condition和多線程通信Event后面在多線程同步再介紹。
threading模塊Thread類的主要函數(shù):
1).Thread.getName(),Thread.setName()
獲取和設(shè)置線程名字。
2).Thread.ident()
獲取線程的標(biāo)示符,是一個(gè)整數(shù)。
3).Thread.is_alive(),Thread.isAlive()
判斷線程是不是活的,即線程是否已經(jīng)結(jié)束。
4).Thread.activeCount()
獲取當(dāng)前活著的所有線程總數(shù),包括主線程main。
5).Thread.join()
使主線程阻塞,知道該子線程執(zhí)行完或者超時(shí),它有一個(gè)參數(shù)timeout表示超時(shí)時(shí)間,默認(rèn)為None。
6).Thread.setDaemon()
有一個(gè)布爾值的參數(shù),默認(rèn)為False,該方法設(shè)置子線程是否隨主線程一起結(jié)束。
看看join方法和setDaemon方法:
importthreading, timeclassMyThread(threading.Thread):def __init__(self):
threading.Thread.__init__(self)defrun(self):print ‘thread start‘time.sleep(3)print ‘thread end‘thread1=MyThread()
thread1.start()
time.sleep(1)print ‘start join‘
#thread1.join()
print ‘end join‘
輸出結(jié)果:
不加thread.join
thread start
start join
end join
thread end
加thread.join
thread start
start join
thread end
end join
主線程中sleep(1)一秒就是為了讓線程被調(diào)度,線程中sleep(3)三秒就是為了讓主線程結(jié)束,從兩種情況的輸出結(jié)果可以看出join的功能。
import threading, time
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print ‘thread start‘
time.sleep(3)
print ‘thread end‘
print ‘main start‘
thread1 = MyThread()
#thread1.setDaemon(True)
thread1.start()
time.sleep(1)
print ‘main end‘
輸出結(jié)果:
setDaemon默認(rèn)為False
main start
thread start
main end
thread end
setDaemon設(shè)置為True
main start
thread start
main end
從打印的結(jié)果可以看出,當(dāng)設(shè)置為True的時(shí)候,線程還在sleep過程就就結(jié)束了,以至于thread end這句都沒有打印出來。
當(dāng)然Thread類還不止這些方法,這些只是常用的方法,通過help(Thread)可以查看。
原文地址:https://www.cnblogs.com/liuye1990/p/9392384.html
總結(jié)
以上是生活随笔為你收集整理的python threading_【python标准库学习】thread,threading(一)多线程的介绍和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python自带gui_Python G
- 下一篇: python open 相对路径_第十四