_thread --- Phân luồng cấp thấp API


Mô-đun này cung cấp các nguyên hàm cấp thấp để làm việc với nhiều luồng (còn được gọi là light-weight processes hoặc tasks) --- nhiều luồng điều khiển chia sẻ không gian dữ liệu chung của chúng. Để đồng bộ hóa, các khóa đơn giản (còn gọi là mutexes hoặc binary semaphores) được cung cấp. Mô-đun threading cung cấp luồng API cấp cao hơn và dễ sử dụng hơn được xây dựng dựa trên mô-đun này.

Thay đổi trong phiên bản 3.7: Mô-đun này trước đây là tùy chọn, bây giờ nó luôn có sẵn.

Mô-đun này xác định các hằng số và hàm sau:

exception _thread.error

Tăng lên về các lỗi cụ thể theo chủ đề.

Thay đổi trong phiên bản 3.3: Đây hiện là từ đồng nghĩa của RuntimeError tích hợp.

_thread.LockType

Đây là loại đối tượng khóa.

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

Bắt đầu một chủ đề mới và trả về mã định danh của nó. Luồng thực thi hàm function với danh sách đối số args (phải là một bộ dữ liệu). Đối số kwargs tùy chọn chỉ định một từ điển các đối số từ khóa.

Khi hàm trả về, luồng sẽ âm thầm thoát ra.

Khi hàm kết thúc với một ngoại lệ chưa được xử lý, sys.unraisablehook() được gọi để xử lý ngoại lệ đó. Thuộc tính object của đối số hook là function. Theo mặc định, dấu vết ngăn xếp được in và sau đó luồng thoát ra (nhưng các luồng khác vẫn tiếp tục chạy).

Khi hàm đưa ra một ngoại lệ SystemExit, nó sẽ bị bỏ qua một cách âm thầm.

Tăng một auditing event _thread.start_new_thread với các đối số function, args, kwargs.

Thay đổi trong phiên bản 3.8: sys.unraisablehook() hiện được sử dụng để xử lý các trường hợp ngoại lệ chưa được xử lý.

_thread.interrupt_main(signum=signal.SIGINT, /)

Mô phỏng tác động của tín hiệu đến luồng chính. Một luồng có thể sử dụng chức năng này để làm gián đoạn luồng chính, mặc dù không có gì đảm bảo rằng sự gián đoạn sẽ xảy ra ngay lập tức.

Nếu được, signum là số tín hiệu cần mô phỏng. Nếu signum không được cung cấp, signal.SIGINT sẽ được mô phỏng.

Nếu tín hiệu đã cho không được Python xử lý (nó được đặt thành signal.SIG_DFL hoặc signal.SIG_IGN), thì hàm này sẽ không hoạt động.

Thay đổi trong phiên bản 3.10: Đối số signum được thêm vào để tùy chỉnh số tín hiệu.

Ghi chú

Điều này không phát ra tín hiệu tương ứng nhưng lên lịch cuộc gọi đến trình xử lý liên quan (nếu nó tồn tại). Nếu bạn muốn phát ra tín hiệu thực sự, hãy sử dụng signal.raise_signal().

_thread.exit()

Tăng ngoại lệ SystemExit. Khi không bị bắt, điều này sẽ khiến luồng thoát ra một cách im lặng.

_thread.allocate_lock()

Trả về một đối tượng khóa mới. Các phương pháp khóa được mô tả dưới đây. Khóa ban đầu được mở khóa.

_thread.get_ident()

Trả về 'mã định danh luồng' của luồng hiện tại. Đây là một số nguyên khác 0. Giá trị của nó không có ý nghĩa trực tiếp; nó được dự định như một cookie ma thuật được sử dụng, ví dụ: để lập chỉ mục một từ điển dữ liệu theo chủ đề cụ thể. Mã nhận dạng luồng có thể được tái sử dụng khi một luồng thoát ra và một luồng khác được tạo.

_thread.get_native_id()

Trả về ID luồng tích phân gốc của luồng hiện tại được hạt nhân gán. Đây là một số nguyên không âm. Giá trị của nó có thể được sử dụng để nhận dạng duy nhất toàn hệ thống luồng cụ thể này (cho đến khi luồng kết thúc, sau đó giá trị có thể được HĐH tái chế).

sẵn có: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD.

Added in version 3.8.

Thay đổi trong phiên bản 3.13: Đã thêm hỗ trợ cho GNU/kFreeBSD.

_thread.stack_size([size])

Trả về kích thước ngăn xếp luồng được sử dụng khi tạo chủ đề mới. Đối số size tùy chọn chỉ định kích thước ngăn xếp sẽ được sử dụng cho các luồng được tạo sau đó và phải bằng 0 (sử dụng nền tảng hoặc mặc định được định cấu hình) hoặc giá trị nguyên dương ít nhất là 32.768 (32 KiB). Nếu size không được chỉ định thì 0 sẽ được sử dụng. Nếu việc thay đổi kích thước ngăn xếp luồng không được hỗ trợ thì RuntimeError sẽ được nâng lên. Nếu kích thước ngăn xếp được chỉ định không hợp lệ, ValueError sẽ được nâng lên và kích thước ngăn xếp không được sửa đổi. 32 KiB hiện là giá trị kích thước ngăn xếp được hỗ trợ tối thiểu để đảm bảo có đủ không gian ngăn xếp cho chính trình thông dịch. Lưu ý rằng một số nền tảng có thể có các hạn chế cụ thể về giá trị cho kích thước ngăn xếp, chẳng hạn như yêu cầu kích thước ngăn xếp tối thiểu > 32 KiB hoặc yêu cầu phân bổ theo bội số của kích thước trang bộ nhớ hệ thống - nên tham khảo tài liệu nền tảng để biết thêm thông tin (trang 4 KiB là phổ biến; sử dụng bội số của 4096 cho kích thước ngăn xếp là phương pháp được đề xuất trong trường hợp không có thông tin cụ thể hơn).

sẵn có: Windows, pthreads.

Nền tảng Unix có hỗ trợ chủ đề POSIX.

_thread.TIMEOUT_MAX

Giá trị tối đa được phép cho tham số timeout của Lock.acquire. Việc chỉ định thời gian chờ lớn hơn giá trị này sẽ tăng OverflowError.

Added in version 3.2.

Khóa đối tượng có các phương thức sau:

lock.acquire(blocking=True, timeout=-1)

Không có bất kỳ đối số tùy chọn nào, phương thức này lấy khóa vô điều kiện, nếu cần sẽ đợi cho đến khi nó được giải phóng bởi một luồng khác (mỗi lần chỉ một luồng có thể lấy được khóa --- đó là lý do tồn tại của chúng).

Nếu đối số blocking xuất hiện, hành động sẽ phụ thuộc vào giá trị của nó: nếu nó sai, khóa chỉ được lấy nếu có thể lấy được ngay lập tức mà không cần chờ đợi, trong khi nếu nó đúng, khóa sẽ được lấy vô điều kiện như trên.

Nếu đối số timeout dấu phẩy động xuất hiện và dương thì nó chỉ định thời gian chờ tối đa tính bằng giây trước khi quay lại. Đối số timeout âm chỉ định thời gian chờ không giới hạn. Bạn không thể chỉ định timeout nếu blocking sai.

Giá trị trả về là True nếu khóa được lấy thành công, False nếu không.

Thay đổi trong phiên bản 3.2: Thông số timeout là mới.

Thay đổi trong phiên bản 3.2: Việc thu thập khóa hiện có thể bị gián đoạn bởi các tín hiệu trên POSIX.

Thay đổi trong phiên bản 3.14: Giờ đây, quá trình thu thập khóa có thể bị gián đoạn bởi các tín hiệu trên Windows.

lock.release()

Mở khóa. Khóa phải được lấy trước đó, nhưng không nhất thiết phải bằng cùng một sợi.

lock.locked()

Trả về trạng thái của khóa: True nếu nó đã được một luồng nào đó lấy được, False nếu không.

Ngoài các phương thức này, các đối tượng khóa cũng có thể được sử dụng thông qua câu lệnh with, ví dụ:

nhập _thread

a_lock = _thread.allocate_lock()

với a_lock:
    print("a_lock bị khóa khi lệnh này thực thi")

Caveats:

  • Các ngắt luôn đi đến luồng chính (ngoại lệ KeyboardInterrupt sẽ được luồng đó nhận.)

  • Gọi sys.exit() hoặc đưa ra ngoại lệ SystemExit tương đương với việc gọi _thread.exit().

  • Khi luồng chính thoát ra, hệ thống sẽ xác định xem các luồng khác có tồn tại hay không. Trên hầu hết các hệ thống, chúng bị giết mà không thực thi các mệnh đề try ... finally hoặc thực thi các hàm hủy đối tượng.