Chạy nhiều luồng tương tự như chạy đồng thời nhiều chương trình khác nhau, nhưng có các lợi ích sau –
Nhiều luồng trong một quy trình chia sẻ cùng một không gian dữ liệu với luồng chính và do đó có thể chia sẻ thông tin hoặc giao tiếp với nhau dễ dàng hơn nếu chúng là các quy trình riêng biệt
Các luồng đôi khi được gọi là các quy trình trọng lượng nhẹ và chúng không yêu cầu nhiều bộ nhớ;
Một luồng có phần mở đầu, trình tự thực hiện và phần kết luận. Nó có một con trỏ lệnh theo dõi vị trí trong ngữ cảnh của nó hiện đang chạy
Nó có thể được làm trống trước [bị gián đoạn]
Nó có thể tạm thời bị treo [còn được gọi là ngủ] trong khi các luồng khác đang chạy - điều này được gọi là năng suất
Bắt đầu một chủ đề mới
Để sinh ra một luồng khác, bạn cần gọi phương thức sau có sẵn trong mô-đun luồng -
thread.start_new_thread [ function, args[, kwargs] ]
Cuộc gọi phương thức này cho phép một cách nhanh chóng và hiệu quả để tạo các luồng mới trong cả Linux và Windows
Cuộc gọi phương thức trả về ngay lập tức và luồng con bắt đầu và gọi hàm với danh sách các đối số đã truyền. Khi chức năng trở lại, luồng kết thúc
Ở đây, args là một bộ đối số; . kwargs là một từ điển tùy chọn của các đối số từ khóa
Thí dụ
#!/usr/bin/python import thread import time # Define a function for the thread def print_time[ threadName, delay]: count = 0 while count < 5: time.sleep[delay] count += 1 print "%s: %s" % [ threadName, time.ctime[time.time[]] ] # Create two threads as follows 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
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009
Mặc dù nó rất hiệu quả đối với luồng cấp thấp, nhưng mô-đun luồng rất hạn chế so với mô-đun luồng mới hơn
Mô-đun luồng
Mô-đun luồng mới hơn có trong Python 2. 4 cung cấp hỗ trợ cấp cao, mạnh mẽ hơn cho các luồng so với mô-đun luồng đã thảo luận trong phần trước
Mô-đun luồng hiển thị tất cả các phương thức của mô-đun luồng và cung cấp một số phương thức bổ sung -
xâu chuỗi. activeCount[] - Trả về số đối tượng luồng đang hoạt động
xâu chuỗi. currentThread[] − Trả về số lượng đối tượng luồng trong điều khiển luồng của trình gọi
xâu chuỗi. enumerate[] - Trả về danh sách tất cả các đối tượng luồng hiện đang hoạt động
Ngoài các phương thức, mô-đun luồng có lớp Thread thực hiện phân luồng. Các phương thức được cung cấp bởi lớp Thread như sau -
run[] - Phương thức run[] là điểm bắt đầu cho một luồng
start[] − Phương thức start[] bắt đầu một luồng bằng cách gọi phương thức run
tham gia [[thời gian]] - Tham gia [] chờ các luồng kết thúc
isAlive[] − Phương thức isAlive[] kiểm tra xem một luồng có còn đang thực thi hay không
getName[] − Phương thức getName[] trả về tên của một luồng
setName[] − Phương thức setName[] đặt tên của một luồng
Tạo chủ đề bằng cách sử dụng mô-đun luồng
Để triển khai một luồng mới bằng mô-đun luồng, bạn phải thực hiện như sau -
Định nghĩa một lớp con mới của lớp Thread
Ghi đè phương thức __init__[self [,args]] để thêm các đối số bổ sung
Sau đó, ghi đè phương thức run[self [,args]] để thực hiện những gì luồng nên làm khi bắt đầu
Một khi bạn đã tạo lớp con Thread mới, bạn có thể tạo một thể hiện của nó và sau đó bắt đầu một luồng mới bằng cách gọi phương thức start[], từ đó gọi phương thức run[]
Thí dụ
#!/usr/bin/python import threading import time exitFlag = 0 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 print_time[self.name, 5, self.counter] print "Exiting " + self.name def print_time[threadName, counter, delay]: while counter: if exitFlag: threadName.exit[] time.sleep[delay] print "%s: %s" % [threadName, time.ctime[time.time[]]] counter -= 1 # Create new threads thread1 = myThread[1, "Thread-1", 1] thread2 = myThread[2, "Thread-2", 2] # Start new Threads thread1.start[] thread2.start[] print "Exiting Main Thread"
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Thu Mar 21 09:10:03 2013 Thread-1: Thu Mar 21 09:10:04 2013 Thread-2: Thu Mar 21 09:10:04 2013 Thread-1: Thu Mar 21 09:10:05 2013 Thread-1: Thu Mar 21 09:10:06 2013 Thread-2: Thu Mar 21 09:10:06 2013 Thread-1: Thu Mar 21 09:10:07 2013 Exiting Thread-1 Thread-2: Thu Mar 21 09:10:08 2013 Thread-2: Thu Mar 21 09:10:10 2013 Thread-2: Thu Mar 21 09:10:12 2013 Exiting Thread-2
Đồng bộ chủ đề
Mô-đun luồng được cung cấp cùng với Python bao gồm một cơ chế khóa dễ thực hiện cho phép bạn đồng bộ hóa các luồng. Một khóa mới được tạo bằng cách gọi phương thức Lock[], trả về khóa mới
Phương thức thu được [chặn] của đối tượng khóa mới được sử dụng để buộc các luồng chạy đồng bộ. Tham số chặn tùy chọn cho phép bạn kiểm soát xem chuỗi có chờ để lấy khóa hay không
Nếu chặn được đặt thành 0, luồng sẽ trả về ngay lập tức với giá trị 0 nếu không lấy được khóa và bằng 1 nếu lấy được khóa. Nếu chặn được đặt thành 1, luồng sẽ chặn và đợi khóa được giải phóng
Phương thức release[] của đối tượng khóa mới được sử dụng để giải phóng khóa khi không còn cần thiết
Thí dụ
#!/usr/bin/python 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 # Get lock to synchronize threads threadLock.acquire[] print_time[self.name, self.counter, 3] # Free lock to release next thread 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 = [] # Create new threads thread1 = myThread[1, "Thread-1", 1] thread2 = myThread[2, "Thread-2", 2] # Start new Threads thread1.start[] thread2.start[] # Add threads to thread list threads.append[thread1] threads.append[thread2] # Wait for all threads to complete for t in threads: t.join[] print "Exiting Main Thread"
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
Starting Thread-1 Starting Thread-2 Thread-1: Thu Mar 21 09:11:28 2013 Thread-1: Thu Mar 21 09:11:29 2013 Thread-1: Thu Mar 21 09:11:30 2013 Thread-2: Thu Mar 21 09:11:32 2013 Thread-2: Thu Mar 21 09:11:34 2013 Thread-2: Thu Mar 21 09:11:36 2013 Exiting Main Thread
Hàng đợi ưu tiên đa luồng
Mô-đun Hàng đợi cho phép bạn tạo một đối tượng hàng đợi mới có thể chứa một số mục cụ thể. Có các phương pháp sau để kiểm soát Hàng đợi -