1. 程式人生 > >python多執行緒threading

python多執行緒threading

                     

本文通過 4個example 介紹python中多執行緒package —— threading的常用用法, 包括呼叫多執行緒, 同步佇列類Queue, Ctrl+c結束多執行緒。

example1.

呼叫10個執行緒, 分別列印0~4, 每列印一個數pause一秒鐘。

code如下所示, 在test()函式中用threading.Thread建立10個執行緒; 一種方法是不要將這些執行緒設定為守護執行緒,如code所示; 一種方法是設定守護執行緒( setDeamon(True)),並用join()讓程式等所有執行緒結束了再退出(即去掉code中的註釋);

#/*********************************************************************
# *-# * Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved# *-# *********************************************************************#-#-#-#/**# * @file b.py# * @author zhangruiqing01([email protected])# * @date 2015/10/28 20:12:33# * @brief-# *--# **/#import timeimport threadingdef printf(i):    for
x in xrange(5):        time.sleep(1)        print i,def test():    thread_list = []    for i in xrange(10):        sthread = threading.Thread(target = printf, args = str(i))#        sthread.setDaemon(True)        sthread.start()        thread_list.append(sthread)#    for i in xrange(10):#        thread_list[i].join()
if __name__ == '__main__':    test()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

結果: $python b.py  0 1 2 3 4 5 6 7 8 9 2 1 0 4 5 6 7 3 8 9 1 2 0 5 6 7 4 3 8 9 2 1 0 6 7 4 3 5 8 9 1 0 2 7 4 635 8 9

example2.

呼叫10個守護執行緒(每個守護執行緒的timeout時間為1s), 分別列印0~4, 每列印一個數pause x秒鐘, x為0~4之間的randint值。

#/***************************************************************************# *-# * Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved# *-# **************************************************************************/#-#-#-#/**# * @file c.py# * @author zhangruiqing01([email protected])# * @date 2015/10/28 20:15:33# * @brief-# *--# **/#import timeimport threadingimport randomdef printf(i):    randtime = random.randint(1,5)    for x in xrange(5):        time.sleep(randtime)        print "T" + str(i), randtime # print T<threadid> randtimedef test():    thread_list = []    for i in xrange(10):        sthread = threading.Thread(target = printf, args = str(i))        sthread.setDaemon(True)        sthread.start()        thread_list.append(sthread)    for i in xrange(10):        thread_list[i].join(1)if __name__ == '__main__':    test()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

結果:

這裡寫圖片描述

從圖中可見,在執行的這10s中, pause x秒的thread被列印了[10/x]次。

example3.

引入Queue, 帶同步功能(enqueue和dequeue不用手動加鎖)的queue類。

在下面的code中,proc函式處理一個thread的操作:      1. dequeue 一個隊頭元素     2. enqueue 5個threadid     3. 重複執行兩次步驟2(epoch<2)

這裡注意proc函式中的最後Q.task_done()表示一個任務(一個dequeue的元素)已經結束;test( )中最後的Q.join()為等待佇列為空才退出程式。

#/***************************************************************************# *-# * Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved# *-# **************************************************************************/#-#-#-#/**# * @file d.py# * @author zhangruiqing01([email protected])# * @date 2015/10/28 20:22:33# * @brief-# *--# **/#import timeimport threadingimport randomimport QueueQ = Queue.Queue()def proc(threadid, epoch):    while True:        time.sleep(1)        try:            ele = Q.get()            print 'Thread ' + str(threadid) + ' get element ' + str(ele)        except Queue.Empty:            print 'Thread ' + str(threadid) + ' get empty queue'            continue        if int(epoch) < 2:            for i in xrange(5):                Q.put(threadid)            epoch = int(epoch) + 1        Q.task_done()def test():    Q.put(1)    thread_list = []    for i in xrange(3):        args = [str(i), str(0)]        sthread = threading.Thread(target = proc, args = args)        sthread.setDaemon(True)        sthread.start()        thread_list.append(sthread)    Q.join()if __name__ == '__main__':    test()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

結果:

PS:最開始get到的1是在test()中put進去的;

這裡寫圖片描述

example4.

程式接收ctrl + c後退出。程式每個thread列印100次threadid,直到ctrl+c退出。

PS: 更好的設計是在try,except後加finally塊, 做到即便不ctrl+c也可以正常退出,就留給大家下面練習吧~

#/***************************************************************************# *-# * Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved# *-# **************************************************************************/#-#-#-#/**# * @file a.py# * @author zhangruiqing01([email protected])# * @date 2015/10/28 20:06:33# * @brief-# *--# **/#import timeimport threadingdef printf(i):    for x in xrange(100):        time.sleep(1)        print i,def test():    for i in xrange(10):        sthread = threading.Thread(target = printf, args = str(i))        sthread.setDaemon(True)        sthread.start()    try:        while 1:            time.sleep(1)    except KeyboardInterrupt:        print 'exit'if __name__ == '__main__':    test()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

執行結果:

這裡寫圖片描述