Python 多線程

Python中使用線程有兩種方式:函數或者用類來包裝線程對象。


函數式:調用thread模塊中的start_new_thread()函數來產生新線程。語法如下:

thread.start_new_thread ( function, args[, kwargs] )

參數說明:

  • function - 線程函數。
  • args - 傳遞給線程函數的參數,他必須是個tuple類型。
  • kwargs - 可選參數。
# -*- coding: UTF-8 -*-

import thread
import time

# 爲線程定義一個函數
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print "%s: %s" % ( threadName, time.ctime(time.time()) )

# 創建兩個線程
try:
   thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print "Error: unable to start thread"

while 1:
   pass


# -*- coding: UTF-8 -*-

import thread
import time

# 爲線程定義一個函數
class Test(object):
   def print_time(self, threadName, delay):
      count = 0
      while count < 5:
        time.sleep(delay)
        count += 1
        print "%s: %s" % ( threadName, time.ctime(time.time()) )

test = Test()

# 創建兩個線程
try:
   thread.start_new_thread( test.print_time, ("Thread-1", 2) )
   thread.start_new_thread( test.print_time, ("Thread-2", 4) )
except:
   print "Error: unable to start thread"

while 1:
   pass


執行以上程序輸出結果如下:

Thread-1: Fri Mar 03 20:36:49 2017
Thread-2: Fri Mar 03 20:36:49 2017
Thread-1: Fri Mar 03 20:36:49 2017
Thread-1: Fri Mar 03 20:36:49 2017
Thread-2: Fri Mar 03 20:36:49 2017
Thread-1: Fri Mar 03 20:36:49 2017
Thread-1: Fri Mar 03 20:36:49 2017
Thread-2: Fri Mar 03 20:36:50 2017
Thread-2: Fri Mar 03 20:36:50 2017
Thread-2: Fri Mar 03 20:36:50 2017

線程的結束一般依靠線程函數的自然結束;也可以在線程函數中調用thread.exit(),他拋出SystemExit exception,達到退出線程的目的。


線程模塊

Python通過兩個標準庫thread和threading提供對線程的支持。thread提供了低級別的、原始的線程以及一個簡單的鎖。

thread 模塊提供的其他方法:

  • threading.currentThread(): 返回當前的線程變量。
  • threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啓動後、結束前,不包括啓動前和終止後的線程。
  • threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果。

除了使用方法外,線程模塊同樣提供了Thread類來處理線程,Thread類提供了以下方法:

  • run(): 用以表示線程活動的方法。
  • start():啓動線程活動。

  • join([time]): 等待至線程中止。這阻塞調用線程直至線程的join() 方法被調用中止-正常退出或者拋出未處理的異常-或者是可選的超時發生。
  • isAlive(): 返回線程是否活動的。
  • getName(): 返回線程名。
  • setName(): 設置線程名。

使用Threading模塊創建線程

使用Threading模塊創建線程,直接從threading.Thread繼承,然後重寫__init__方法和run方法:

# -*- coding: UTF-8 -*-

import threading
import time

exitFlag = 0

class myThread (threading.Thread):   #繼承父類threading.Thread
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
		
    def run(self):                   #把要執行的代碼寫到run函數裏面 線程在創建後會直接運行run函數 
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            thread.exit()
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

# 創建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 開啓線程
thread1.start()
thread2.start()

print "Exiting Main Thread"

以上程序執行結果如下;

Starting Thread-1Starting Thread-2
 Exiting Main Thread

Thread-1: Fri Mar 03 20:46:52 2017
Thread-2: Fri Mar 03 20:46:53 2017
Thread-1: Fri Mar 03 20:46:53 2017
Thread-1: Fri Mar 03 20:46:54 2017
Thread-2: Fri Mar 03 20:46:55 2017
Thread-1: Fri Mar 03 20:46:55 2017
Thread-1: Fri Mar 03 20:46:56 2017
Exiting Thread-1
Thread-2: Fri Mar 03 20:46:57 2017
Thread-2: Fri Mar 03 20:46:59 2017
Thread-2: Fri Mar 03 20:47:01 2017
Exiting Thread-2

線程同步

如果多個線程共同對某個數據修改,則可能出現不可預料的結果,爲了保證數據的正確性,需要對多個線程進行同步。

使用Thread對象的Lock和Rlock可以實現簡單的線程同步,這兩個對象都有acquire方法和release方法,對於那些需要每次只允許一個線程操作的數據,可以將其操作放到acquire和release方法之間。

# -*- coding: UTF-8 -*-

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name
       # 獲得鎖,成功獲得鎖定後返回True
       # 可選的timeout參數不填時將一直阻塞直到獲得鎖定
       # 否則超時後將返回False
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 釋放鎖
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 創建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 開啓新線程
thread1.start()
thread2.start()

# 添加線程到線程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有線程完成
for t in threads:
    t.join()
print "Exiting Main Thread"

















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章