Python線程操作


一、全局鎖

1、在Python中,Python代碼的執行由Python虛擬機來控制,而在Python虛擬機中,同一時刻只有一個線程在執行,就像單CPU的系統中運行多個進程那樣,內存中可以存放多個程序,但在任意時刻,只有一個程序在CPU中運行。同樣的,在Python解釋器中可以“運行”多個線程,但在任意時刻,只有一個線程在Python解釋器中運行。

2、對Python虛擬機的訪問由全局解釋器鎖【GIL】來控制,正是這個鎖能保證同一時刻只有一個線程在運行。

3、多線程環境中,Python虛擬機的執行方式為:

1. 設置GIL

2. 切換到一個線程去運行

3. 運行:

   a. 指定數量的字節碼指令,或者

   b. 線程主動讓出控制(可以調用time.sleep(0)

4. 把線程設置為睡眠狀態

5. 解鎖GIL

6. 再次重復以上所有步驟

二、線程模塊

 Python提供了【thread】和【threading】模塊。在多線程編程中,建議使用【threading】模塊,這是因為:

1、在【thread】模塊中,當主線程退出時,其他沒有被清除的線程沒有運行結束就會被退出。但在【threading】模塊中能確保所有的“重要的”子線程(這里的重要的子線程指的是守護線程)運行結束后,進程才會結束

2、在【threading】模塊是更高級的線程模塊,它不僅提供了Thread類,還提供了線程同步機制

thread模塊

 內建函數

1、thread.start_new_thread(function, args[, kwargs=None])

     這個函數用來啟動一個線程,其參數含義分別為:

     function:線程任務函數

     args:線程任務函數的參數【以元組的方式傳入】

     kwargs:可選的參數

2、thread.interrupt_main()

     這個函數用來中斷主線程

3、thread.exit()

     這個函數用來退出線程

4、thread.get_ident()

     這個函數用來獲取線程標識號

5、thread.allocate_lock()

     這個線程用來獲取LockType對象

6、thread.stack_size([size])

     這個線程用來返回創建新線程棧容量,其參數含義為:

     size:指定創建新線程棧容量,該參數取值為0或不小於32,768(32KB)
LockType對象

1、lock.acquire([waitflag])

     這個函數用來申請鎖對象,若是獲得鎖對象返回True,否則返回False

2、lock.release()

     這個函數用來釋放鎖對象【使用該函數前提是獲取鎖對象】

3、lock.locked()

     這個函數用來獲取對象鎖的狀態,若是已被鎖住則返回True,否則返回False
示例:
>>> import thread

>>> sum = 0

/*****************線程任務函數**********************/

>>> def add(lock):

    global sum               #設置為全局變量

    lock.acquire()          #加鎖

    i = 1

    while(i < 3):

        sum = sum + 10

        i = i + 1

    id = thread.get_ident() #線程號

    print "Thread ",id,"set sum = ",sum

lock.release()          #釋放鎖

/***********************啟動線程**************************/

>>> def startTask():

    lock = thread.allocate_lock() #申請鎖對象

    task_0 = thread.start_new_thread(add,(lock,))

    task_1 = thread.start_new_thread(add,(lock,))

/************************測試**************************/

>>> startTask()

>>> Thread  764 set sum =  20

Thread  5240 set sum =  40

threading模塊

【threading】模塊式以【thread】為基礎,但提供更高的線程類以及同步機制。

內建函數

1、threading.activeCount()

     這個函數用來獲取【active Thread】的數目

2、threading.enumerate()

     這個函數用來獲取【active Thread】列表。注意:包括中斷的線程以及還未開始的線程

3、threading.currentThread()

     這個函數用來獲取當前運行的【Thread object】

4、threading.settrace(func)

     這個函數用來設置所有通過【threading】模塊啟動的線程的跟蹤函數,該函數在【Thread Object】的【run】方法執行前被調用,其參數含義為:

     func:跟蹤函數名

5、threading.setprofile(func)

     這個函數用來設置所有通過【threading】模塊啟動的線程的profile函數

6、threading.Event()

     這個工廠函數用來獲取一個新的【Event Object】

7、threading.Lock()

     這個工廠函數用來獲取【LockType Object】

8、threading.RLock()

     這個工廠函數用來獲取【RLock Object】

9、threading.Condition()

     這個工廠函數用來獲取【Condition Object】

10、threading.Semaphore([value])

     這個工廠函數用來獲取【Semaphore Object】

11、threading.BoundedSemaphore([value])

     這個工廠函數用來獲取【Bounded Semaphore Object】
內建類

1、class threading.local

     類似Java的ThreadLocal

2、class threading.Thread(group=None, target=None, name=None,             

                                            args=(), kwargs={})

     構造函數參數含義如下:

     target:Thread類中【run】函數調用的函數

     name:指定線程的名,默認線程名格式為:【Thread-N】

     args:target函數的參數

   1)、start()

         啟動線程,值得注意的是:該方法只能被線程調用一次,否則拋出異常RuntimeError

   2)、run()

         線程任務函數。常被子類重寫,類似Java Thread類的run函數

   3)、is_alive()

        判斷線程是否【alive】

   4)、setDaemon()

        將線程設置為守護線程

3、class threading.Timer(interval, function, args=[], kwargs={})

      Timer類繼承threading.Thread類,其參數含義為:

      interval:線程時間執行時間間隔,以秒為單位

      function:Thread類中run函數執行的目標函數

      args:目標函數的參數

     1)、cancel()

           取消Timer任務的執行
示例
/***************************Timer實例************************/

>>> def putOutNumber():

    id = threading.currentThread().getName()

    print id,'Hello'

>>> def startTimer():

    timer = threading.Timer(60,putOutNumber)

    timer.start()

>>> startTimer()

>>> Thread-1 Hello

/****************繼承Thread與Semaphore實例********************/

>>> import threading

>>> class MyThread(threading.Thread):

    def __init__(self,name,semaphore):

        threading.Thread.__init__(self,None,None,name,None)

        self.semaphore = semaphore

    def run(self): #override run function

        self.semaphore.acquire()

        i = 1

        while(i < 3):

            print self.getName(),' print ',i

            i = i + 1

        self.semaphore.release()

 

>>> def startTask():

    semaphore = threading.Semaphore()

    thread_0 = MyThread("Thread_0",semaphore)

    thread_1 = MyThread("Thread_1",semaphore)

    thread_0.start()

    thread_1.start()

 

>>> startTask()

>>> Thread_0  print  1

    Thread_0  print  2

    Thread_1  print  1

    Thread_1  print  2

/*********************進程之間進行通信************************/

>>> class ManagerThread(threading.Thread):

    def __init__(self,name,event):

        threading.Thread.__init__(self,None,None,name,None)

        self.event = event

    def run(self): #override run function

        print self.getName(),' say ','go'

        self.event.set()

>>> class PeopleThread(threading.Thread):

    def __init__(self,name,event):

        threading.Thread.__init__(self,None,None,name,None)

        self.event = event

    def run(self):

        self.event.wait()

        print self.getName(),' start ','go'

 

>>> def startTask():

    event = threading.Event()

    m_thread = ManagerThread("Manager",event)

    p_thread = PeopleThread("People",event)

    p_thread.start()

m_thread.start()

/*************************測試****************************/

>>> startTask()

>>> Manager  say  go

    People  start  go

Mutex

內建類

 

1、class mutex.mutex

     mutex對象有兩個屬性:鎖和隊列。當鎖沒有被鎖時,隊列是空的。

    /*********************mutex Object 函數********************/

    1)、mutex.test()

          這個函數檢測mutex是否被鎖

     2)、 mutex.testandset()

           這個函數用來檢測mutex是否被鎖,若是沒有鎖住,則鎖住並返回True,否則返回False。值得注意的是:這個函數是原子操作

     3)、mutex.lock(function, argument)

           這個函數用來執行函數function(argument)【前提是mutex沒有被鎖】。如果mutex鎖被鎖,則將function(argument)放入隊列中

     4)、mutex.unlock()

          這個函數用來解鎖mutex【前提是隊列是空的】。如果隊列不是空的,則在隊列中取出第一個function(argument)執行並不解鎖
示例
>>> import mutex

>>> def putOutTask(text):

     print text

>>> def startTask():

    m_metux = mutex.mutex()

    m_metux.lock(putOutTask,'I am task_0')

    m_metux.lock(putOutTask,'T am task_1')

    m_metux.lock(putOutTask,'I am task_2')

    m_metux.lock(putOutTask,'T am task_3')

    m_metux.lock(putOutTask,'I am task_4')

    m_metux.lock(putOutTask,'T am task_5')

    while(m_metux.test()):

        m_metux.unlock()

m_metux.unlock()

/**************************測試***************************/

>>> startTask()

I am task_0

T am task_1

I am task_2

T am task_3

I am task_4

T am task_5


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM