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
執行結果: