Giao tiếp giữa các luồng (Inter-Thread Communication) đề cập đến quá trình cho phép giao tiếp và đồng bộ hóa giữa các luồng trong một chương trình đa luồng của Python.
Nói chung, các luồng trong Python chia sẻ cùng một không gian bộ nhớ trong một tiến trình, điều này cho phép chúng trao đổi dữ liệu và phối hợp hoạt động của mình thông qua các biến, đối tượng và cơ chế đồng bộ hóa chuyên dụng được cung cấp bởi mô-đun threading .
Để tạo điều kiện cho việc giao tiếp giữa các luồng, mô-đun threading cung cấp nhiều nguyên tắc đồng bộ hóa khác nhau như: đối tượng Locks, Events, Conditions và Semaphores. Trong hướng dẫn này, bạn sẽ học cách sử dụng đối tượng Event và Condition để cung cấp giao tiếp giữa các luồng trong một chương trình đa luồng.
Một đối tượng Event quản lý trạng thái của một cờ nội bộ để các luồng có thể chờ hoặc thiết lập. Đối tượng Event cung cấp các phương thức để kiểm soát trạng thái của cờ này, cho phép các luồng đồng bộ hóa hoạt động của họ dựa trên các điều kiện chia sẻ.
Cờ ban đầu là false và trở thành true với phương thức set() và được thiết lập lại thành false với phương thức clear(). Phương thức wait() sẽ chặn cho đến khi cờ trở thành true.
Các phương thức chính của đối tượng Event như sau −
Đoạn mã sau cố gắng mô phỏng dòng giao thông được điều khiển bởi trạng thái của tín hiệu giao thông, hoặc là XANH (GREEN) hoặc ĐỎ (RED).
Có hai luồng trong chương trình, nhắm đến hai hàm khác nhau. Hàm signal_state() định kỳ thiết lập và đặt lại sự kiện cho biết sự thay đổi tín hiệu từ XANH sang ĐỎ.
Hàm traffic_flow() chờ sự kiện được thiết lập và chạy một vòng lặp cho đến khi nó vẫn được thiết lập.
from threading import Event, Thread import time terminate = False def signal_state(): global terminate while not terminate: time.sleep(0.5) print("Traffic Police Giving GREEN Signal") event.set() time.sleep(1) print("Traffic Police Giving RED Signal") event.clear() def traffic_flow(): global terminate num = 0 while num < 10 and not terminate: print("Waiting for GREEN Signal") event.wait() print("GREEN Signal ... Traffic can move") while event.is_set() and not terminate: num += 1 print("Vehicle No:", num," Crossing the Signal") time.sleep(1) print("RED Signal ... Traffic has to wait") event = Event() t1 = Thread(target=signal_state) t2 = Thread(target=traffic_flow) t1.start() t2.start() # Terminate the threads after some time time.sleep(5) terminate = True # join all threads to complete t1.join() t2.join() print("Exiting Main Thread")
Khi thực thi đoạn mã trên, bạn sẽ nhận được đầu ra sau:
Waiting for GREEN Signal Traffic Police Giving GREEN Signal GREEN Signal ... Traffic can move Vehicle No: 1 Crossing the Signal Traffic Police Giving RED Signal RED Signal ... Traffic has to wait Waiting for GREEN Signal Traffic Police Giving GREEN Signal GREEN Signal ... Traffic can move Vehicle No: 2 Crossing the Signal Vehicle No: 3 Crossing the Signal Traffic Police Giving RED Signal Traffic Police Giving GREEN Signal Vehicle No: 4 Crossing the Signal Traffic Police Giving RED Signal RED Signal ... Traffic has to wait Traffic Police Giving GREEN Signal Traffic Police Giving RED Signal Exiting Main Thread
Đối tượng Condition trong mô-đun threading của Python cung cấp một cơ chế đồng bộ hóa nâng cao hơn. Nó cho phép các luồng chờ đợi một thông báo từ một luồng khác trước khi tiếp tục. Đối tượng Condition luôn được liên kết với một khóa và cung cấp các cơ chế để báo hiệu giữa các luồng.
Dưới đây là cú pháp của lớp threading.Condition() −
threading.Condition(lock=None)
Dưới đây là các phương thức chính của đối tượng Condition −
Ví dụ này minh họa một hình thức giao tiếp giữa các luồng đơn giản sử dụng đối tượng Condition của module threading trong Python. Ở đây, thread_a và thread_b được giao tiếp bằng cách sử dụng một đối tượng Condition, thread_a chờ cho đến khi nhận được thông báo từ thread_b . thread_b ngủ trong 2 giây trước khi thông báo cho thread_a và sau đó kết thúc.
from threading import Condition, Thread import time c = Condition() def thread_a(): print("Thread A started") with c: print("Thread A waiting for permission...") c.wait() print("Thread A got permission!") print("Thread A finished") def thread_b(): print("Thread B started") with c: time.sleep(2) print("Notifying Thread A...") c.notify() print("Thread B finished") Thread(target=thread_a).start() Thread(target=thread_b).start()
Output
Khi thực thi đoạn mã trên, bạn sẽ nhận được đầu ra sau:
Thread A started Thread A waiting for permission... Thread B started Notifying Thread A... Thread B finished Thread A got permission! Thread A finished
Dưới đây là một đoạn mã khác minh họa cách đối tượng Condition được sử dụng để cung cấp giao tiếp giữa các luồng. Trong đoạn mã này, luồng t2 thực hiện hàm taskB(), và luồng t1 thực hiện hàm taskA(). Luồng t1 chiếm điều kiện và thông báo cho nó.
Vào thời điểm đó, luồng t2 đang ở trạng thái chờ. Sau khi điều kiện được giải phóng, luồng đang chờ sẽ tiếp tục tiêu thụ số ngẫu nhiên được tạo ra bởi hàm thông báo.
from threading import Condition, Thread import time import random numbers = [] def taskA(c): for _ in range(5): with c: num = random.randint(1, 10) print("Generated random number:", num) numbers.append(num) print("Notification issued") c.notify() time.sleep(0.3) def taskB(c): for i in range(5): with c: print("waiting for update") while not numbers: c.wait() print("Obtained random number", numbers.pop()) time.sleep(0.3) c = Condition() t1 = Thread(target=taskB, args=(c,)) t2 = Thread(target=taskA, args=(c,)) t1.start() t2.start() t1.join() t2.join() print("Done")
Khi bạn thực thi đoạn mã này, nó sẽ tạo ra kết quả sau output −
waiting for update Generated random number: 2 Notification issued Obtained random number 2 Generated random number: 5 Notification issued waiting for update Obtained random number 5 Generated random number: 1 Notification issued waiting for update Obtained random number 1 Generated random number: 9 Notification issued waiting for update Obtained random number 9 Generated random number: 2 Notification issued waiting for update Obtained random number 2 Done