Đa luồng Python trong lớp

cung cấp giao diện cấp cao hơn để đẩy các tác vụ tới luồng nền mà không chặn thực thi luồng gọi, trong khi vẫn có thể truy xuất kết quả của chúng khi cần

cung cấp giao diện an toàn cho luồng để trao đổi dữ liệu giữa các luồng đang chạy

cung cấp một cách tiếp cận khác để đạt được sự đồng thời ở cấp độ tác vụ mà không yêu cầu sử dụng nhiều luồng hệ điều hành

Ghi chú

Trong Python 2. x, mô-đun này chứa _______ 7 tên cho một số phương thức và chức năng. Chúng không được dùng nữa kể từ Python 3. 10, nhưng chúng vẫn được hỗ trợ để tương thích với Python 2. 5 và thấp hơn

Chi tiết triển khai CPython. Trong CPython, do đó, chỉ một luồng có thể thực thi mã Python cùng một lúc (mặc dù một số thư viện định hướng hiệu suất nhất định có thể khắc phục hạn chế này). Nếu bạn muốn ứng dụng của mình tận dụng tốt hơn tài nguyên tính toán của các máy đa lõi, bạn nên sử dụng hoặc. Tuy nhiên, phân luồng vẫn là mô hình phù hợp nếu bạn muốn chạy đồng thời nhiều tác vụ liên kết I/O

không phải Emscripten, không phải WASI

Mô-đun này không hoạt động hoặc không khả dụng trên nền tảng WebAssugging

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
0 và
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
1. Xem để biết thêm thông tin

Mô-đun này xác định các chức năng sau

phân luồng. active_count()

Trả về số lượng đối tượng hiện đang sống. Số lượng trả về bằng với độ dài của danh sách được trả về bởi

Hàm

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
4 là bí danh không dùng nữa cho hàm này

phân luồng. current_thread()

Trả về đối tượng hiện tại, tương ứng với luồng điều khiển của người gọi. Nếu luồng điều khiển của người gọi không được tạo thông qua mô-đun, một đối tượng luồng giả với chức năng hạn chế được trả về

Hàm

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
7 là bí danh không dùng nữa cho hàm này

phân luồng. excepthook(args , /)

Xử lý ngoại lệ chưa được phát hiện được đưa ra bởi

Đối số args có các thuộc tính sau

  • exc_type. loại ngoại lệ

  • ex_value. Giá trị ngoại lệ, có thể là

    # Consume one item
    with cv:
        while not an_item_is_available():
            cv.wait()
        get_an_available_item()
    
    # Produce one item
    with cv:
        make_an_item_available()
        cv.notify()
    
    9

  • exc_traceback. Truy nguyên ngoại lệ, có thể là

    # Consume one item
    with cv:
        while not an_item_is_available():
            cv.wait()
        get_an_available_item()
    
    # Produce one item
    with cv:
        make_an_item_available()
        cv.notify()
    
    9

  • chủ đề. Chủ đề đưa ra ngoại lệ, có thể là

    # Consume one item
    with cv:
        while not an_item_is_available():
            cv.wait()
        get_an_available_item()
    
    # Produce one item
    with cv:
        make_an_item_available()
        cv.notify()
    
    9

Nếu exc_type là , ngoại lệ sẽ bị bỏ qua. Nếu không, ngoại lệ được in ra trên

Nếu chức năng này đưa ra một ngoại lệ, được gọi để xử lý nó

có thể được ghi đè để kiểm soát cách xử lý các ngoại lệ chưa được phát hiện do

Lưu trữ exc_value bằng móc tùy chỉnh có thể tạo chu kỳ tham chiếu. Nó phải được xóa một cách rõ ràng để phá vỡ chu trình tham chiếu khi không còn cần thiết ngoại lệ

Lưu trữ chủ đề bằng móc tùy chỉnh có thể phục hồi chủ đề nếu nó được đặt thành một đối tượng đang được hoàn thiện. Tránh lưu trữ luồng sau khi móc tùy chỉnh hoàn thành để tránh phục hồi các đối tượng

Xem thêm

xử lý các ngoại lệ chưa được phát hiện

Mới trong phiên bản 3. 8

phân luồng. __ngoại trừ móc__

Giữ giá trị ban đầu của. Nó được lưu để giá trị ban đầu có thể được khôi phục trong trường hợp chúng bị thay thế bằng các đối tượng bị hỏng hoặc thay thế

Mới trong phiên bản 3. 10

phân luồng. get_ident()

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

Mới trong phiên bản 3. 3

phân luồng. get_native_id()

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

Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX

Mới trong phiên bản 3. 8

phân luồng. liệt kê()

Trả về danh sách tất cả các đối tượng hiện đang hoạt động. Danh sách này bao gồm các luồng daemon và các đối tượng luồng giả được tạo bởi. Nó loại trừ các chủ đề đã kết thúc và các chủ đề chưa được bắt đầu. Tuy nhiên, luồng chính luôn là một phần của kết quả, ngay cả khi bị chấm dứt

phân luồng. main_thread()

Trả lại đối tượng chính. Trong điều kiện bình thường, luồng chính là luồng mà trình thông dịch Python được bắt đầu

Mới trong phiên bản 3. 4

phân luồng. settrace(chức năng)

Đặt chức năng theo dõi cho tất cả các luồng bắt đầu từ mô-đun. Func sẽ được truyền cho từng luồng, trước khi phương thức của nó được gọi

phân luồng. lấy()

Nhận chức năng theo dõi như được thiết lập bởi

Mới trong phiên bản 3. 10

phân luồng. setprofile(chức năng)

Đặt chức năng hồ sơ cho tất cả các luồng bắt đầu từ mô-đun. Func sẽ được truyền cho từng luồng, trước khi phương thức của nó được gọi

phân luồng. lấy hồ sơ()

Nhận chức năng hồ sơ như được thiết lập bởi

Mới trong phiên bản 3. 10

phân luồng. stack_size([kích thước])

Trả về kích thước ngăn xếp luồng được sử dụng khi tạo luồng mới. Đối số kích thước tùy chọn chỉ định kích thước ngăn xếp sẽ được sử dụng cho các chuỗi được tạo sau đó và phải là 0 (sử dụng nền tảng hoặc mặc định được định cấu hình) hoặc giá trị số nguyên dương ít nhất là 32.768 (32 KiB). Nếu kích thước không được chỉ định, 0 đượ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ợ, a sẽ được nâng lên. Nếu kích thước ngăn xếp được chỉ định không hợp lệ, a 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 tối thiểu được hỗ trợ để đảm bảo đủ 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ể đối với các giá trị đối với 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

Windows, pthread

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

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

phân luồng. TIMEOUT_MAX

Giá trị tối đa được phép cho tham số thời gian chờ của các chức năng chặn (, , , v.v. ). Chỉ định thời gian chờ lớn hơn giá trị này sẽ tăng

Mới trong phiên bản 3. 2

Mô-đun này định nghĩa một số lớp, được trình bày chi tiết trong các phần bên dưới

Thiết kế của mô-đun này dựa trên mô hình phân luồng của Java. Tuy nhiên, trong đó Java tạo các khóa và biến điều kiện hành vi cơ bản của mọi đối tượng, thì chúng là các đối tượng riêng biệt trong Python. Lớp của Python hỗ trợ một tập hợp con hành vi của lớp Chủ đề của Java; . Các phương thức tĩnh của lớp Thread của Java, khi được triển khai, được ánh xạ tới các hàm cấp mô-đun

Tất cả các phương pháp được mô tả dưới đây được thực thi nguyên tử

Dữ liệu chủ đề cục bộ

Dữ liệu luồng cục bộ là dữ liệu có giá trị cụ thể theo luồng. Để quản lý dữ liệu cục bộ của luồng, chỉ cần tạo một thể hiện của (hoặc một lớp con) và lưu trữ các thuộc tính trên đó

________số 8_______

Các giá trị của cá thể sẽ khác nhau đối với các luồng riêng biệt

lớp phân luồng. cục bộ

Một lớp đại diện cho dữ liệu cục bộ luồng

Để biết thêm chi tiết và các ví dụ mở rộng, hãy xem chuỗi tài liệu của mô-đun

maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)
8

Đối tượng chủ đề

Lớp đại diện cho một hoạt động được chạy trong một luồng điều khiển riêng biệt. Có hai cách để xác định hoạt động. bằng cách chuyển một đối tượng có thể gọi được tới hàm tạo hoặc bằng cách ghi đè phương thức trong một lớp con. Không có phương thức nào khác (ngoại trừ hàm tạo) được ghi đè trong một lớp con. Nói cách khác, chỉ ghi đè

with pool_sema:
    conn = connectdb()
    try:
        # .. use connection ...
    finally:
        conn.close()
1 và các phương thức của lớp này

Khi một đối tượng luồng được tạo, hoạt động của nó phải được bắt đầu bằng cách gọi phương thức của luồng. Điều này gọi phương thức trong một luồng điều khiển riêng biệt

Khi hoạt động của chuỗi được bắt đầu, chuỗi được coi là 'còn sống'. Nó ngừng hoạt động khi phương thức của nó kết thúc - thông thường hoặc bằng cách đưa ra một ngoại lệ chưa được xử lý. Phương thức kiểm tra xem thread còn sống hay không

Các luồng khác có thể gọi phương thức của luồng. Điều này chặn luồng đang gọi cho đến khi luồng có phương thức được gọi kết thúc

Một chủ đề có một tên. Tên có thể được chuyển đến hàm tạo và đọc hoặc thay đổi thông qua thuộc tính

Nếu phương thức đưa ra một ngoại lệ, được gọi để xử lý nó. Theo mặc định, bỏ qua âm thầm

Một luồng có thể được gắn cờ là một “luồng daemon”. Ý nghĩa của cờ này là toàn bộ chương trình Python sẽ thoát khi chỉ còn lại các luồng daemon. Giá trị ban đầu được kế thừa từ chuỗi tạo. Cờ có thể được đặt thông qua thuộc tính hoặc đối số hàm tạo daemon

Ghi chú

Chủ đề daemon bị dừng đột ngột khi tắt máy. Tài nguyên của họ (chẳng hạn như tệp đang mở, giao dịch cơ sở dữ liệu, v.v. ) có thể không được phát hành đúng cách. Nếu bạn muốn các luồng của mình dừng một cách duyên dáng, hãy làm cho chúng không phải daemon và sử dụng cơ chế báo hiệu phù hợp, chẳng hạn như

Có một đối tượng "chủ đề chính"; . Nó không phải là một chủ đề daemon

Có khả năng "đối tượng chuỗi giả" được tạo. Đây là các đối tượng luồng tương ứng với “luồng lạ”, là luồng điều khiển bắt đầu bên ngoài mô-đun luồng, chẳng hạn như trực tiếp từ mã C. Các đối tượng luồng giả có chức năng hạn chế; . Chúng không bao giờ bị xóa, vì không thể phát hiện ra sự chấm dứt của các luồng ngoài hành tinh

lớp phân luồng. Chủ đề(nhóm=Không có, target=None, name=None, args=(), kwargs={}, *, daemon=None)

Hàm tạo này phải luôn được gọi với các đối số từ khóa. Đối số là

nhóm nên là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9;

target là đối tượng có thể gọi được gọi theo phương thức. Mặc định là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, nghĩa là không có gì được gọi

tên là tên chủ đề. Theo mặc định, một tên duy nhất được tạo theo dạng “Chủ đề-N” trong đó N là một số thập phân nhỏ hoặc “Chủ đề-N (mục tiêu)” trong đó “mục tiêu” là _______14_______0 nếu đối số mục tiêu được chỉ định

args là một danh sách hoặc bộ đối số cho lệnh gọi đích. Mặc định là

b = Barrier(2, timeout=5)

def server():
    start_server()
    b.wait()
    while True:
        connection = accept_connection()
        process_server_connection(connection)

def client():
    b.wait()
    while True:
        connection = make_connection()
        process_client_connection(connection)
1

kwargs là một từ điển các đối số từ khóa cho lệnh gọi đích. Mặc định là

b = Barrier(2, timeout=5)

def server():
    start_server()
    b.wait()
    while True:
        connection = accept_connection()
        process_server_connection(connection)

def client():
    b.wait()
    while True:
        connection = make_connection()
        process_client_connection(connection)
2

Nếu không phải là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, trình nền sẽ đặt rõ ràng liệu luồng có phải là trình nền hay không. Nếu
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9 (mặc định), thuộc tính daemon được kế thừa từ luồng hiện tại

Nếu lớp con ghi đè hàm tạo, nó phải đảm bảo gọi hàm tạo của lớp cơ sở (

b = Barrier(2, timeout=5)

def server():
    start_server()
    b.wait()
    while True:
        connection = accept_connection()
        process_server_connection(connection)

def client():
    b.wait()
    while True:
        connection = make_connection()
        process_client_connection(connection)
5) trước khi thực hiện bất kỳ điều gì khác với luồng

Đã thay đổi trong phiên bản 3. 10. Sử dụng tên mục tiêu nếu đối số tên bị bỏ qua.

Đã thay đổi trong phiên bản 3. 3. Đã thêm đối số daemon.

bắt đầu()

Bắt đầu hoạt động của chủ đề

Nó phải được gọi nhiều nhất một lần cho mỗi đối tượng luồng. Nó sắp xếp để phương thức của đối tượng được gọi trong một luồng điều khiển riêng biệt

Phương thức này sẽ tăng if được gọi nhiều lần trên cùng một đối tượng luồng

chạy()

Phương thức đại diện cho hoạt động của luồng

Bạn có thể ghi đè phương thức này trong một lớp con. Phương thức tiêu chuẩn gọi đối tượng có thể gọi được truyền cho hàm tạo của đối tượng làm đối số đích, nếu có, với các đối số vị trí và từ khóa được lấy từ các đối số args và kwargs tương ứng

Sử dụng danh sách hoặc bộ dữ liệu làm đối số args được truyền cho có thể đạt được hiệu quả tương tự

Ví dụ

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1

tham gia(hết thời gian=Không có)

Chờ cho đến khi chủ đề kết thúc. Điều này chặn luồng đang gọi cho đến khi luồng có phương thức được gọi kết thúc - thông thường hoặc thông qua một ngoại lệ chưa được xử lý - hoặc cho đến khi hết thời gian chờ tùy chọn xảy ra

Khi đối số thời gian chờ xuất hiện và không phải là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, thì đối số đó phải là số dấu phẩy động chỉ định thời gian chờ cho thao tác tính bằng giây (hoặc phân số của nó). Như luôn trả về
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, bạn phải gọi sau để quyết định xem thời gian chờ có xảy ra hay không – nếu luồng vẫn còn hoạt động, cuộc gọi đã hết thời gian chờ

Khi đối số hết thời gian chờ không xuất hiện hoặc

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, hoạt động sẽ bị chặn cho đến khi luồng kết thúc

Một chủ đề có thể được tham gia nhiều lần

tăng một nếu một nỗ lực được thực hiện để tham gia chủ đề hiện tại vì điều đó sẽ gây ra bế tắc. Đó cũng là một lỗi đối với một luồng trước khi nó được bắt đầu và cố gắng làm như vậy sẽ gây ra ngoại lệ tương tự

tên

Một chuỗi chỉ được sử dụng cho mục đích nhận dạng. Nó không có ngữ nghĩa. Nhiều chủ đề có thể được đặt tên giống nhau. Tên ban đầu được đặt bởi hàm tạo

getName()setName()

API getter/setter không dùng nữa cho ;

Không dùng nữa kể từ phiên bản 3. 10

nhận dạng

'Số nhận dạng chủ đề' của chủ đề này hoặc

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9 nếu chủ đề chưa được bắt đầu. Đây là một số nguyên khác không. xem chức năng. Số nhận dạng luồng có thể được tái chế khi một luồng thoát và một luồng khác được tạo. Mã định danh khả dụng ngay cả sau khi chuỗi đã thoát

native_id

ID chủ đề (

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
04) của chủ đề này, như được chỉ định bởi hệ điều hành (nhân). Đây là một số nguyên không âm hoặc
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9 nếu chủ đề chưa được bắt đầu. xem chức năng. Giá trị này có thể được sử dụng để xác định duy nhất luồng cụ thể này trên toàn hệ thống (cho đến khi luồng kết thúc, sau đó hệ điều hành có thể tái chế giá trị này)

Ghi chú

Tương tự như ID quy trình, ID luồng chỉ hợp lệ (được đảm bảo là duy nhất trên toàn hệ thống) từ khi luồng được tạo cho đến khi luồng kết thúc

Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD

Mới trong phiên bản 3. 8

is_alive()

Trả về xem thread còn sống hay không

Phương thức này trả về

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 ngay trước khi phương thức bắt đầu cho đến ngay sau khi phương thức kết thúc. Hàm mô-đun trả về danh sách tất cả các luồng còn sống

yêu tinh

Một giá trị boolean cho biết luồng này có phải là luồng daemon hay không (

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07) hay không (
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12). Điều này phải được đặt trước khi được gọi, nếu không thì được nâng lên. Giá trị ban đầu của nó được kế thừa từ chuỗi tạo;

Toàn bộ chương trình Python thoát khi không còn luồng không phải daemon nào còn sống

isDaemon()setDaemon()

API getter/setter không dùng nữa cho ;

Không dùng nữa kể từ phiên bản 3. 10

Khóa đối tượng

Khóa nguyên thủy là nguyên thủy đồng bộ hóa không thuộc sở hữu của một luồng cụ thể khi bị khóa. Trong Python, nó hiện là nguyên mẫu đồng bộ hóa mức thấp nhất hiện có, được triển khai trực tiếp bởi mô-đun mở rộng

Khóa nguyên thủy ở một trong hai trạng thái, "đã khóa" hoặc "đã mở khóa". Nó được tạo ở trạng thái mở khóa. Nó có hai phương pháp cơ bản, và. Khi trạng thái được mở khóa, thay đổi trạng thái thành bị khóa và quay lại ngay lập tức. Khi trạng thái bị khóa, chặn cho đến khi một cuộc gọi đến trong một chuỗi khác thay đổi trạng thái đó thành mở khóa, sau đó cuộc gọi đặt lại thành bị khóa và quay lại. Phương thức chỉ nên được gọi ở trạng thái bị khóa; . Nếu một nỗ lực được thực hiện để giải phóng một khóa đã được mở khóa, một điểm sẽ được nâng lên

Ổ khóa cũng hỗ trợ

Khi có nhiều hơn một luồng bị chặn trong khi chờ trạng thái chuyển sang mở khóa, chỉ một luồng tiếp tục khi một cuộc gọi đặt lại trạng thái thành mở khóa;

Tất cả các phương pháp được thực hiện nguyên tử

lớp phân luồng. Khóa

Lớp triển khai các đối tượng khóa nguyên thủy. Khi một luồng đã có được khóa, các nỗ lực tiếp theo để có được khối đó, cho đến khi nó được giải phóng;

Lưu ý rằng

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
29 thực sự là một hàm xuất xưởng trả về một phiên bản hiệu quả nhất của lớp Khóa cụ thể được nền tảng hỗ trợ

có được(chặn=Đúng, timeout=- 1)

Nhận khóa, chặn hoặc không chặn

Khi được gọi với đối số chặn được đặt thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 (mặc định), chặn cho đến khi khóa được mở khóa, sau đó đặt thành bị khóa và trả về
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07

Khi được gọi với đối số chặn được đặt thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12, không chặn. Nếu một cuộc gọi có chặn được đặt thành
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 sẽ chặn, hãy trả lại
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 ngay lập tức;

Khi được gọi với đối số thời gian chờ dấu phẩy động được đặt thành giá trị dương, hãy chặn tối đa số giây được chỉ định theo thời gian chờ và miễn là không thể lấy được khóa. Đối số thời gian chờ của

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
36 chỉ định thời gian chờ không giới hạn. Cấm chỉ định thời gian chờ khi chặn là
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12

Giá trị trả về là

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 nếu khóa được lấy thành công,
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 nếu không (ví dụ: nếu hết thời gian chờ)

Đã thay đổi trong phiên bản 3. 2. Tham số thời gian chờ 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 nếu triển khai luồng cơ bản hỗ trợ nó.

phát hành()

Phát hành một khóa. Điều này có thể được gọi từ bất kỳ luồng nào, không chỉ luồng đã lấy khóa

Khi khóa bị khóa, đặt lại thành mở khóa và quay lại. Nếu bất kỳ chủ đề nào khác bị chặn đang chờ khóa được mở khóa, hãy cho phép chính xác một trong số chúng tiếp tục

Khi được gọi trên một khóa đã mở khóa, a được nâng lên

không có giá trị quay lại

bị khóa()

Trả lại

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 nếu khóa được mua

RLock đối tượng

Khóa reentrant là nguyên thủy đồng bộ hóa có thể được mua lại nhiều lần bởi cùng một luồng. Trong nội bộ, nó sử dụng các khái niệm về “chủ đề sở hữu” và “cấp độ đệ quy” ngoài trạng thái khóa/mở khóa được sử dụng bởi các khóa nguyên thủy. Ở trạng thái bị khóa, một số luồng sở hữu khóa;

Để khóa khóa, một luồng gọi phương thức của nó; . Để mở khóa, một luồng gọi phương thức của nó. / các cặp cuộc gọi có thể được lồng vào nhau;

Khóa Reentrant cũng hỗ trợ

lớp phân luồng. RLock

Lớp này thực hiện các đối tượng khóa reentrant. Một khóa reentrant phải được phát hành bởi chủ đề có được nó. Khi một luồng đã nhận được khóa truy cập lại, luồng đó có thể lấy lại khóa đó mà không bị chặn;

Lưu ý rằng

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
49 thực sự là một hàm xuất xưởng trả về một phiên bản hiệu quả nhất của lớp RLock cụ thể được nền tảng hỗ trợ

có được(chặn=Đúng, timeout=- 1)

Nhận khóa, chặn hoặc không chặn

Khi được gọi mà không có đối số. nếu chủ đề này đã sở hữu khóa, hãy tăng mức đệ quy lên một và quay lại ngay lập tức. Mặt khác, nếu một chủ đề khác sở hữu khóa, hãy chặn cho đến khi khóa được mở khóa. Khi khóa được mở khóa (không thuộc sở hữu của bất kỳ luồng nào), sau đó lấy quyền sở hữu, đặt mức đệ quy thành một và quay lại. Nếu có nhiều luồng bị chặn chờ cho đến khi khóa được mở khóa, thì mỗi lần chỉ một luồng có thể giành quyền sở hữu khóa. Không có giá trị trả lại trong trường hợp này

Khi được gọi với đối số chặn được đặt thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07, hãy thực hiện tương tự như khi được gọi mà không có đối số và trả về
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07

Khi được gọi với đối số chặn được đặt thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12, không chặn. Nếu một cuộc gọi không có đối số sẽ bị chặn, hãy trả lại
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 ngay lập tức;

Khi được gọi với đối số thời gian chờ dấu phẩy động được đặt thành giá trị dương, hãy chặn tối đa số giây được chỉ định theo thời gian chờ và miễn là không thể lấy được khóa. Trả lại

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 nếu đã lấy được khóa,
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 nếu hết thời gian chờ

Đã thay đổi trong phiên bản 3. 2. Tham số thời gian chờ là mới.

phát hành()

Phát hành khóa, giảm mức đệ quy. Nếu sau khi giảm, nó bằng 0, hãy đặt lại khóa thành mở khóa (không thuộc sở hữu của bất kỳ chuỗi nào) và nếu bất kỳ chuỗi nào khác bị chặn đang chờ khóa được mở khóa, hãy cho phép chính xác một trong số chúng tiếp tục. Nếu sau khi giảm, mức đệ quy vẫn khác không, thì khóa vẫn bị khóa và thuộc sở hữu của luồng gọi

Chỉ gọi phương thức này khi luồng gọi sở hữu khóa. A được nâng lên nếu phương thức này được gọi khi khóa được mở khóa

không có giá trị quay lại

Đối tượng điều kiện

Một biến điều kiện luôn được liên kết với một số loại khóa; . Chuyển một vào rất hữu ích khi một số biến điều kiện phải chia sẻ cùng một khóa. Khóa là một phần của đối tượng điều kiện. bạn không cần phải theo dõi nó một cách riêng biệt

Một biến điều kiện tuân theo. sử dụng câu lệnh

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
58 để có được khóa liên quan trong suốt thời gian của khối kèm theo. Các phương thức và cũng gọi các phương thức tương ứng của khóa được liên kết

Các phương thức khác phải được gọi với khóa liên quan được giữ. Phương thức giải phóng khóa, sau đó chặn cho đến khi một luồng khác đánh thức nó bằng cách gọi hoặc. Sau khi thức tỉnh, lấy lại khóa và quay trở lại. Cũng có thể chỉ định thời gian chờ

Phương thức đánh thức một trong các luồng đang chờ biến điều kiện, nếu có đang chờ. Phương thức đánh thức tất cả các luồng đang chờ biến điều kiện

Ghi chú. các phương thức và không giải phóng khóa;

Phong cách lập trình điển hình sử dụng các biến điều kiện sử dụng khóa để đồng bộ hóa quyền truy cập vào một số trạng thái được chia sẻ; . Ví dụ: đoạn mã sau là tình huống chung giữa nhà sản xuất và người tiêu dùng với dung lượng bộ đệm không giới hạn

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()

Vòng lặp

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
75 kiểm tra điều kiện của ứng dụng là cần thiết vì có thể quay lại sau một khoảng thời gian dài tùy ý và điều kiện nhắc cuộc gọi có thể không còn đúng nữa. Đây là vốn có của lập trình đa luồng. Phương pháp này có thể được sử dụng để tự động kiểm tra điều kiện và giảm bớt việc tính toán thời gian chờ

# Consume an item
with cv:
    cv.wait_for(an_item_is_available)
    get_an_available_item()

Để chọn giữa và , hãy xem xét liệu một thay đổi trạng thái có thể thú vị đối với chỉ một hoặc một số luồng đang chờ hay không. e. g. trong một tình huống điển hình của nhà sản xuất-người tiêu dùng, việc thêm một mục vào bộ đệm chỉ cần đánh thức một luồng người tiêu dùng

lớp phân luồng. Điều kiện(khóa=Không)

Lớp này thực hiện các đối tượng biến điều kiện. Một biến điều kiện cho phép một hoặc nhiều luồng đợi cho đến khi chúng được thông báo bởi một luồng khác

Nếu đối số lock được đưa ra và không phải là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, thì nó phải là một đối tượng hoặc và nó được sử dụng làm khóa cơ bản. Mặt khác, một đối tượng mới được tạo và sử dụng làm khóa bên dưới

Đã thay đổi trong phiên bản 3. 3. đã thay đổi từ hàm xuất xưởng thành lớp.

thu được(*đối số)

Có được khóa cơ bản. Phương thức này gọi phương thức tương ứng trên khóa bên dưới;

phát hành()

Thả khóa bên dưới. Phương thức này gọi phương thức tương ứng trên khóa bên dưới;

chờ(hết thời gian=Không có)

Đợi cho đến khi được thông báo hoặc cho đến khi hết thời gian chờ. Nếu luồng đang gọi chưa nhận được khóa khi phương thức này được gọi, a sẽ được nâng lên

Phương pháp này giải phóng khóa cơ bản, sau đó chặn cho đến khi nó được đánh thức bởi một hoặc gọi cho cùng một biến điều kiện trong một luồng khác hoặc cho đến khi hết thời gian chờ tùy chọn xảy ra. Sau khi được đánh thức hoặc hết thời gian chờ, nó sẽ lấy lại khóa và quay lại

Khi đối số thời gian chờ xuất hiện và không phải là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, thì đối số đó phải là số dấu phẩy động chỉ định thời gian chờ cho thao tác tính bằng giây (hoặc phân số của nó)

Khi khóa bên dưới là một , thì nó không được giải phóng bằng phương thức của nó, vì điều này có thể không thực sự mở khóa khi nó được mua lại nhiều lần theo cách đệ quy. Thay vào đó, một giao diện bên trong của lớp được sử dụng, giao diện này thực sự mở khóa nó ngay cả khi nó đã được sử dụng đệ quy nhiều lần. Sau đó, một giao diện nội bộ khác được sử dụng để khôi phục mức đệ quy khi khóa được lấy lại

Giá trị trả về là

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 trừ khi hết thời gian chờ nhất định, trong trường hợp đó là
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12

Đã thay đổi trong phiên bản 3. 2. Trước đây, phương thức luôn trả về

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9.

wait_for(predicate , timeout=None)

Chờ cho đến khi một điều kiện đánh giá là đúng. vị ngữ phải là một giá trị có thể gọi được, kết quả sẽ được hiểu là giá trị boolean. Thời gian chờ có thể được cung cấp cho thời gian chờ tối đa

Phương thức tiện ích này có thể gọi lặp đi lặp lại cho đến khi vị từ được thỏa mãn hoặc cho đến khi hết thời gian chờ. Giá trị trả về là giá trị trả về cuối cùng của biến vị ngữ và sẽ đánh giá thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 nếu phương thức hết thời gian chờ

Bỏ qua tính năng hết thời gian chờ, việc gọi phương thức này gần tương đương với việc viết

while not predicate():
    cv.wait()

Do đó, các quy tắc tương tự được áp dụng như với. Khóa phải được giữ khi được gọi và được lấy lại khi trả lại. Vị từ được đánh giá với khóa được giữ

Mới trong phiên bản 3. 2

thông báo(n=1)

Theo mặc định, đánh thức một luồng đang chờ trong điều kiện này, nếu có. Nếu luồng đang gọi chưa nhận được khóa khi phương thức này được gọi, a sẽ được nâng lên

Phương thức này đánh thức tối đa n luồng đang chờ biến điều kiện;

Việc triển khai hiện tại đánh thức đúng n luồng, nếu có ít nhất n luồng đang chờ. Tuy nhiên, không an toàn khi dựa vào hành vi này. Việc triển khai được tối ưu hóa trong tương lai đôi khi có thể đánh thức hơn n luồng

Ghi chú. một luồng được đánh thức không thực sự quay trở lại từ cuộc gọi của nó cho đến khi nó có thể lấy lại khóa. Vì không nhả khóa nên người gọi nó phải

notify_all()

Đánh thức tất cả các chủ đề đang chờ trong điều kiện này. Phương pháp này hoạt động như , nhưng đánh thức tất cả các chuỗi đang chờ thay vì một. Nếu luồng đang gọi chưa nhận được khóa khi phương thức này được gọi, a sẽ được nâng lên

Phương thức

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
03 là bí danh không dùng nữa cho phương thức này

Đối tượng Semaphore

Đây là một trong những nguyên tắc đồng bộ hóa lâu đời nhất trong lịch sử khoa học máy tính, được phát minh bởi nhà khoa học máy tính đầu tiên người Hà Lan Edsger W. Dijkstra (anh ấy đã sử dụng tên

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
04 và
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
05 thay vì và )

Một semaphore quản lý một bộ đếm nội bộ được giảm dần theo mỗi cuộc gọi và tăng lên theo mỗi cuộc gọi. Bộ đếm không bao giờ có thể xuống dưới 0;

Semaphores cũng hỗ trợ

lớp phân luồng. Semaphore(giá trị=1)

Lớp này cài đặt các đối tượng semaphore. Một semaphore quản lý một bộ đếm nguyên tử biểu thị số lần gọi trừ đi số lần gọi, cộng với một giá trị ban đầu. Phương thức chặn nếu cần thiết cho đến khi nó có thể quay lại mà không làm cho bộ đếm âm. Nếu không được cung cấp, giá trị mặc định là 1

Đối số tùy chọn đưa ra giá trị ban đầu cho bộ đếm nội bộ; . Nếu giá trị đã cho nhỏ hơn 0, được nâng lên

Đã thay đổi trong phiên bản 3. 3. đã thay đổi từ hàm xuất xưởng thành lớp.

có được(chặn=Đúng, timeout=None)

Có được một semaphore

Khi được gọi mà không có đối số

  • Nếu bộ đếm bên trong lớn hơn 0 khi nhập, hãy giảm nó đi một và trả về

    >>> from threading import Thread
    >>> t = Thread(target=print, args=[1])
    >>> t.run()
    1
    >>> t = Thread(target=print, args=(1,))
    >>> t.run()
    1
    
    07 ngay lập tức

  • Nếu bộ đếm bên trong bằng 0 khi vào, hãy chặn cho đến khi được đánh thức bằng lệnh gọi đến. Sau khi được đánh thức (và bộ đếm lớn hơn 0), giảm bộ đếm đi 1 và trả về

    >>> from threading import Thread
    >>> t = Thread(target=print, args=[1])
    >>> t.run()
    1
    >>> t = Thread(target=print, args=(1,))
    >>> t.run()
    1
    
    07. Chính xác một chủ đề sẽ được đánh thức bởi mỗi cuộc gọi đến. Không nên dựa vào thứ tự các luồng được đánh thức

Khi được gọi với tính năng chặn được đặt thành

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12, không chặn. Nếu một cuộc gọi không có đối số sẽ bị chặn, hãy trả lại
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12 ngay lập tức;

Khi được gọi với thời gian chờ khác với

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, nó sẽ chặn trong tối đa giây hết thời gian chờ. Nếu thu thập không hoàn tất thành công trong khoảng thời gian đó, hãy trả lại
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
12. Trả lại
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 nếu không

Đã thay đổi trong phiên bản 3. 2. Tham số thời gian chờ là mới.

phát hành(n=1)

Phát hành một semaphore, tăng bộ đếm bên trong lên n. Khi nó bằng 0 trên mục nhập và các luồng khác đang đợi nó trở lại lớn hơn 0 lần nữa, hãy đánh thức n trong số các luồng đó

Đã thay đổi trong phiên bản 3. 9. Đã thêm tham số n để giải phóng nhiều luồng đang chờ cùng một lúc.

lớp phân luồng. BoundedSemaphore(giá trị=1)

Lớp triển khai các đối tượng semaphore có giới hạn. Semaphore có giới hạn kiểm tra để đảm bảo giá trị hiện tại của nó không vượt quá giá trị ban đầu. Nếu nó làm, được nâng lên. Trong hầu hết các tình huống, đèn hiệu được sử dụng để bảo vệ các tài nguyên có dung lượng hạn chế. Nếu semaphore được phát hành quá nhiều lần, đó là dấu hiệu của một lỗi. Nếu không được cung cấp, giá trị mặc định là 1

Đã thay đổi trong phiên bản 3. 3. đã thay đổi từ hàm xuất xưởng thành lớp.

Ví dụ

Semaphores thường được sử dụng để bảo vệ các tài nguyên có dung lượng hạn chế, chẳng hạn như máy chủ cơ sở dữ liệu. Trong bất kỳ tình huống nào mà kích thước của tài nguyên là cố định, bạn nên sử dụng một semaphore có giới hạn. Trước khi sinh ra bất kỳ luồng worker nào, luồng chính của bạn sẽ khởi tạo semaphore

maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)

Sau khi được sinh ra, worker thread gọi các phương thức thu thập và giải phóng của semaphore khi chúng cần kết nối với máy chủ

with pool_sema:
    conn = connectdb()
    try:
        # .. use connection ...
    finally:
        conn.close()

Việc sử dụng semaphore có giới hạn giúp giảm khả năng lỗi lập trình khiến semaphore được giải phóng nhiều hơn mức thu được sẽ không bị phát hiện

Đối tượng sự kiện

Đây là một trong những cơ chế đơn giản nhất để giao tiếp giữa các luồng. một luồng báo hiệu một sự kiện và các luồng khác chờ đợi nó

Một đối tượng sự kiện quản lý một cờ nội bộ có thể được đặt thành true với phương thức và đặt lại thành false với phương thức. Phương pháp chặn cho đến khi cờ là đúng

lớp phân luồng. Sự kiện

Lớp thực hiện các đối tượng sự kiện. Một sự kiện quản lý cờ có thể được đặt thành true với phương thức và đặt lại thành false với phương thức. Phương pháp chặn cho đến khi cờ là đúng. Cờ ban đầu là sai

Đã thay đổi trong phiên bản 3. 3. đã thay đổi từ hàm xuất xưởng thành lớp.

is_set()

Trả về

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 khi và chỉ khi cờ nội bộ là đúng

Phương thức

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
36 là bí danh không được dùng nữa cho phương thức này

đặt()

Đặt cờ nội bộ thành true. Tất cả các chủ đề đang chờ nó trở thành sự thật được đánh thức. Các chủ đề gọi khi cờ là đúng sẽ hoàn toàn không bị chặn

xóa()

Đặt lại cờ nội bộ thành sai. Sau đó, cuộc gọi chủ đề sẽ chặn cho đến khi được gọi để đặt lại cờ nội bộ thành đúng

chờ(hết thời gian=Không có)

Chặn cho đến khi cờ nội bộ là true. Nếu cờ nội bộ là đúng khi vào, hãy quay lại ngay lập tức. Mặt khác, chặn cho đến khi một chuỗi khác gọi để đặt cờ thành true hoặc cho đến khi hết thời gian chờ tùy chọn xảy ra

Khi đối số thời gian chờ xuất hiện và không phải là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9, thì đối số đó phải là số dấu phẩy động chỉ định thời gian chờ cho thao tác tính bằng giây (hoặc phân số của nó)

Phương thức này trả về

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 khi và chỉ khi cờ nội bộ đã được đặt thành true, trước cuộc gọi chờ hoặc sau khi bắt đầu chờ, do đó, nó sẽ luôn trả về
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 trừ khi hết thời gian chờ và thao tác hết thời gian chờ

Đã thay đổi trong phiên bản 3. 1. Trước đây, phương thức luôn trả về

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9.

Đối tượng hẹn giờ

Lớp này đại diện cho một hành động chỉ được chạy sau một khoảng thời gian nhất định - một bộ đếm thời gian. là một lớp con của và như vậy cũng có chức năng như một ví dụ về tạo chủ đề tùy chỉnh

Bộ hẹn giờ được bắt đầu, như với các luồng, bằng cách gọi phương thức

with pool_sema:
    conn = connectdb()
    try:
        # .. use connection ...
    finally:
        conn.close()
3 của chúng. Có thể dừng bộ định thời (trước khi hành động của nó bắt đầu) bằng cách gọi phương thức. Khoảng thời gian mà bộ hẹn giờ sẽ đợi trước khi thực hiện hành động của nó có thể không hoàn toàn giống với khoảng thời gian do người dùng chỉ định

Ví dụ

def hello():
    print("hello, world")

t = Timer(30.0, hello)
t.start()  # after 30 seconds, "hello, world" will be printed

lớp phân luồng. Bộ hẹn giờ(khoảng thời gian , chức năng, args=None, kwargs=None)

Tạo một bộ đếm thời gian sẽ chạy chức năng với các đối số args và đối số từ khóa kwargs, sau khi khoảng thời gian giây trôi qua. Nếu đối số là

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9 (mặc định) thì một danh sách trống sẽ được sử dụng. Nếu kwargs là
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
9 (mặc định) thì một lệnh trống sẽ được sử dụng

Đã thay đổi trong phiên bản 3. 3. đã thay đổi từ hàm xuất xưởng thành lớp.

hủy()

Dừng bộ đếm thời gian và hủy bỏ việc thực hiện hành động của bộ đếm thời gian. Điều này sẽ chỉ hoạt động nếu bộ hẹn giờ vẫn đang trong giai đoạn chờ

đối tượng rào cản

Mới trong phiên bản 3. 2

Lớp này cung cấp một nguyên mẫu đồng bộ hóa đơn giản để sử dụng bởi một số luồng cố định cần đợi lẫn nhau. Mỗi luồng cố gắng vượt qua rào cản bằng cách gọi phương thức và sẽ chặn cho đến khi tất cả các luồng đã thực hiện cuộc gọi của chúng. Tại thời điểm này, các luồng được giải phóng đồng thời

Rào chắn có thể được tái sử dụng nhiều lần cho cùng một số luồng

Ví dụ, đây là một cách đơn giản để đồng bộ hóa luồng máy khách và máy chủ

b = Barrier(2, timeout=5)

def server():
    start_server()
    b.wait()
    while True:
        connection = accept_connection()
        process_server_connection(connection)

def client():
    b.wait()
    while True:
        connection = make_connection()
        process_client_connection(connection)

lớp phân luồng. Rào cản(các bên , hành động=None, timeout=None)

Tạo một đối tượng rào cản cho các bên số chủ đề. Một hành động, khi được cung cấp, là một hành động có thể gọi được để được gọi bởi một trong các luồng khi chúng được giải phóng. thời gian chờ là giá trị thời gian chờ mặc định nếu không có giá trị nào được chỉ định cho phương thức

chờ(hết thời gian=Không có)

Vượt qua rào cản. Khi tất cả các chủ đề tham gia rào cản đã gọi chức năng này, tất cả chúng sẽ được giải phóng đồng thời. Nếu thời gian chờ được cung cấp, nó sẽ được sử dụng ưu tiên hơn bất kỳ thời gian chờ nào được cung cấp cho hàm tạo của lớp

Giá trị trả về là một số nguyên trong phạm vi từ 0 đến bên – 1, khác nhau đối với mỗi luồng. Điều này có thể được sử dụng để chọn một chủ đề để thực hiện một số công việc vệ sinh đặc biệt, e. g

i = barrier.wait()
if i == 0:
    # Only one thread needs to print this
    print("passed the barrier")

Nếu một hành động được cung cấp cho hàm tạo, thì một trong các luồng sẽ gọi nó trước khi được giải phóng. Nếu cuộc gọi này gây ra lỗi, rào cản sẽ được đưa vào trạng thái bị hỏng

Nếu cuộc gọi hết thời gian, rào cản được đưa vào trạng thái bị hỏng

Phương pháp này có thể đưa ra một ngoại lệ nếu rào cản bị hỏng hoặc đặt lại trong khi một chuỗi đang chờ

đặt lại()

Trả hàng rào về trạng thái trống, mặc định. Bất kỳ chủ đề nào đang chờ nó sẽ nhận được ngoại lệ

Lưu ý rằng việc sử dụng chức năng này có thể yêu cầu một số đồng bộ hóa bên ngoài nếu có các luồng khác không xác định được trạng thái. Nếu một rào cản bị phá vỡ, có thể tốt hơn là bỏ nó đi và tạo một rào cản mới

hủy bỏ()

Đặt rào cản vào trạng thái bị hỏng. Điều này khiến mọi cuộc gọi đang hoạt động hoặc trong tương lai không thành công với. Sử dụng ví dụ này nếu một trong các luồng cần hủy bỏ, để tránh làm bế tắc ứng dụng

Có thể tốt hơn là chỉ cần tạo rào cản với giá trị thời gian chờ hợp lý để tự động bảo vệ chống lại một trong các luồng bị trục trặc

tiệc tùng

Số lượng chủ đề cần thiết để vượt qua rào cản

n_waiting

Số lượng chủ đề hiện đang chờ đợi trong hàng rào

vỡ

Một giá trị boolean là

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
07 nếu hàng rào ở trạng thái bị hỏng

ngoại lệ phân luồng. Lỗi BrokenBarrier

Ngoại lệ này, một lớp con của , được nâng lên khi đối tượng được đặt lại hoặc bị hỏng

Sử dụng khóa, điều kiện và semaphores trong câu lệnh >>> from threading import Thread >>> t = Thread(target=print, args=[1]) >>> t.run() 1 >>> t = Thread(target=print, args=(1,)) >>> t.run() 1 58

Tất cả các đối tượng được cung cấp bởi mô-đun này có các phương thức

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
19 và
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
20 có thể được sử dụng làm trình quản lý ngữ cảnh cho một câu lệnh. Phương thức
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
19 sẽ được gọi khi khối được nhập và
>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
20 sẽ được gọi khi khối được thoát. Do đó, đoạn mã sau

Sử dụng đa luồng trong Python có tốt không?

Đa luồng trong Python hợp lý hóa việc sử dụng tài nguyên hiệu quả vì các luồng chia sẻ cùng một bộ nhớ và không gian dữ liệu . Nó cũng cho phép xuất hiện đồng thời nhiều tác vụ và giảm thời gian phản hồi. Điều này cải thiện hiệu suất.

Lớp nào có thể được sử dụng để triển khai luồng trong Python?

Để tạo chuỗi của riêng chúng ta trong Python, chúng ta sẽ muốn làm cho lớp của mình hoạt động như một chuỗi. Đối với điều này, chúng ta nên phân lớp lớp của mình từ Lớp chủ đề . Khi một Chủ đề khởi động, nó thực hiện một số khởi tạo cơ bản và sau đó gọi phương thức run() của nó, phương thức này gọi hàm mục tiêu được truyền cho hàm tạo.

Vấn đề với đa luồng trong Python là gì?

Nhược điểm. Khi chuyển đổi ngữ cảnh xảy ra, nó chặn tiến trình, vì tiến trình đang duy trì các luồng nên các luồng cũng chặn. Ứng dụng đa luồng không thể tận dụng đa xử lý .

Đa luồng có nhanh hơn trong Python không?

Đây là lý do tại sao đa luồng Python có thể giúp tăng tốc độ lớn. Bộ xử lý có thể chuyển đổi giữa các luồng bất cứ khi nào một trong số chúng sẵn sàng thực hiện một số công việc. Sử dụng mô-đun luồng trong Python hoặc bất kỳ ngôn ngữ được giải thích nào khác với GIL thực sự có thể dẫn đến giảm hiệu suất