Trong Python, hiện tại độ ưu tiên của luồng không được hỗ trợ trực tiếp bởi mô-đun threading . Khác với Java, Python không hỗ trợ độ ưu tiên của luồng, nhóm luồng, hoặc một số cơ chế điều khiển luồng như hủy, dừng, tạm dừng, tiếp tục hoặc ngắt các luồng. Mặc dù các luồng Python được thiết kế đơn giản và dựa trên mô hình Java's threading một cách lỏng lẻo. Điều này là do Khóa Bộ thông dịch Toàn cầu (GIL) của Python, điều khiển các luồng Python.
Tuy nhiên, bạn có thể mô phỏng hành vi dựa trên ưu tiên bằng cách sử dụng các kỹ thuật như thời gian ngủ, logic lập lịch tùy chỉnh trong các luồng hoặc sử dụng mô-đun bổ sung quản lý các ưu tiên tác vụ.
Bạn có thể mô phỏng độ ưu tiên của luồng bằng cách giới thiệu độ trễ hoặc sử dụng các cơ chế khác để kiểm soát thứ tự thực thi của các luồng. Một cách phổ biến để mô phỏng độ ưu tiên của luồng là điều chỉnh thời gian ngủ của các luồng của bạn.
Các luồng có độ ưu tiên thấp sẽ ngủ lâu hơn, trong khi các luồng có độ ưu tiên cao sẽ ngủ ngắn hơn.
Dưới đây là một ví dụ đơn giản để minh họa cách tùy chỉnh độ ưu tiên của các luồng bằng cách sử dụng độ trễ trong các luồng Python. Trong ví dụ này, Thread-2 hoàn thành trước Thread-1 vì nó có giá trị ưu tiên thấp hơn, dẫn đến thời gian ngủ ngắn hơn.
import threading import time class DummyThread(threading.Thread): def __init__(self, name, priority): threading.Thread.__init__(self) self.name = name self.priority = priority def run(self): name = self.name time.sleep(1.0 * self.priority) print(f"{name} thread with priority {self.priority} is running") # Creating threads with different priorities t1 = DummyThread(name='Thread-1', priority=4) t2 = DummyThread(name='Thread-2', priority=1) # Starting the threads t1.start() t2.start() # Waiting for both threads to complete t1.join() t2.join() print('All Threads are executed')
Output
Khi thực thi chương trình trên, bạn sẽ nhận được các kết quả sau −
Thread-2 thread with priority 1 is running Thread-1 thread with priority 4 is running All Threads are executed
Trên hệ điều hành Windows, bạn có thể thao tác với độ ưu tiên của luồng bằng cách sử dụng mô-đun ctypes , đây là một trong những mô-đun chuẩn của Python được sử dụng để tương tác với API của Windows.
Ví dụ này minh họa cách đặt mức độ ưu tiên của các luồng trong Python trên hệ thống Windows bằng cách sử dụng mô-đun ctypes .
import threading import ctypes import time # Constants for Windows API w32 = ctypes.windll.kernel32 SET_THREAD = 0x20 PRIORITIZE_THE_THREAD = 1 class MyThread(threading.Thread): def __init__(self, start_event, name, iterations): super().__init__() self.start_event = start_event self.thread_id = None self.iterations = iterations self.name = name def set_priority(self, priority): if not self.is_alive(): print('Cannot set priority for a non-active thread') return thread_handle = w32.OpenThread(SET_THREAD, False, self.thread_id) success = w32.SetThreadPriority(thread_handle, priority) w32.CloseHandle(thread_handle) if not success: print('Failed to set thread priority:', w32.GetLastError()) def run(self): self.thread_id = w32.GetCurrentThreadId() self.start_event.wait() while self.iterations: print(f"{self.name} running") start_time = time.time() while time.time() - start_time < 1: pass self.iterations -= 1 # Create an event to synchronize thread start start_event = threading.Event() # Create threads thread_normal = MyThread(start_event, name='normal', iterations=4) thread_high = MyThread(start_event, name='high', iterations=4) # Start the threads thread_normal.start() thread_high.start() # Adjusting priority of 'high' thread thread_high.set_priority(PRIORITIZE_THE_THREAD) # Trigger thread execution start_event.set()
Output
Khi thực thi đoạn mã này trong trình thông dịch Python của bạn, bạn sẽ nhận được các kết quả sau −
high running normal running high running normal running high running normal running high running normal running
Mô-đun queue trong thư viện chuẩn của Python rất hữu ích trong lập trình đa luồng khi thông tin phải được trao đổi một cách an toàn giữa nhiều luồng. Lớp Priority Queue trong mô-đun này thực hiện tất cả các ngữ nghĩa khóa cần thiết.
Với hàng đợi ưu tiên, các mục được giữ theo thứ tự (sử dụng mô-đun heapq ) và mục có giá trị thấp nhất được truy xuất trước.
Các đối tượng Queue có các phương thức sau để điều khiển Queue −
get() − Hàm get() loại bỏ và trả về một mục từ hàng đợi.
put() − Phương thức put thêm một mục vào hàng đợi.
qsize() − Hàm qsize() trả về số lượng mục hiện có trong hàng đợi.
empty() − Hàm empty( ) trả về True nếu hàng đợi rỗng; ngược lại, trả về False.
full() − phương thức full() trả về True nếu hàng đợi đầy; ngược lại, trả về False.
queue.PriorityQueue(maxsize=0)
Đây là Constructor cho một hàng đợi ưu tiên. maxsize là một số nguyên đặt giới hạn tối đa cho số lượng mục có thể được đặt trong hàng đợi. Nếu maxsize nhỏ hơn hoặc bằng không, kích thước hàng đợi là vô hạn.
Các mục có giá trị thấp nhất được truy xuất trước (mục có giá trị thấp nhất là mục sẽ được trả về bởi min(entries)). Một mẫu điển hình cho các mục là một tuple ở dạng -
(priority_number, data)
Ví dụ này minh họa việc sử dụng lớp PriorityQueue trong mô-đun queue để quản lý độ ưu tiên tác vụ giữa hai luồng.
from time import sleep from random import random, randint from threading import Thread from queue import PriorityQueue queue = PriorityQueue() def producer(queue): print('Producer: Running') for i in range(5): # create item with priority value = random() priority = randint(0, 5) item = (priority, value) queue.put(item) # wait for all items to be processed queue.join() queue.put(None) print('Producer: Done') def consumer(queue): print('Consumer: Running') while True: # get a unit of work item = queue.get() if item is None: break sleep(item[1]) print(item) queue.task_done() print('Consumer: Done') producer = Thread(target=producer, args=(queue,)) producer.start() consumer = Thread(target=consumer, args=(queue,)) consumer.start() producer.join() consumer.join()
Output
Khi thực thi, nó sẽ tạo ra đầu ra sau:
Producer: Running Consumer: Running (0, 0.15332707626852804) (2, 0.4730737391435892) (2, 0.8679231358257962) (3, 0.051924220435665025) (4, 0.23945882716108446) Producer: Done Consumer: Done