Trong hướng dẫn này, chúng ta sẽ tìm hiểu sâu về các luồng trong Python. Chúng tôi sẽ bắt đầu bằng cách trình bày những gì chúng bao gồm, sau đó chúng tôi sẽ đề cập đến cách bạn có thể xác định các luồng đơn giản của riêng mình trong các chương trình Python của mình và cuối cùng chúng tôi sẽ đề cập đến tất cả các cách bạn có thể làm việc với các luồng đơn giản này trong một Python đơn giản
Chủ đề là gì?
Các chủ đề về cơ bản chỉ là các luồng hướng dẫn được sắp xếp. Tôi. e. làm điều này 5 lần và sau đó kết thúc. Chúng có thể được lên lịch để chạy bởi hệ điều hành và có thể chạy song song trên nhiều lõi hoặc đồng thời trên một lõi
Các luồng thường nằm trong một quy trình gốc, quy trình này chúng ta sẽ đề cập sau trong khóa học và thường bao gồm 4 điều
- Bộ đếm chương trình
- Một chồng
- Một tập hợp các thanh ghi
- Mã định danh
Các luồng trong một hệ điều hành thường có thể tương tác với các tài nguyên được chia sẻ và thực sự có thể giao tiếp giữa nhiều luồng. Vì họ có thể chia sẻ các tài nguyên như bộ nhớ, nên họ cũng có thể sửa đổi mọi thứ theo cách đồng thời hoặc thậm chí song song. Tuy nhiên, khi hai luồng bắt đầu sửa đổi điều gì đó đồng thời, điều quan trọng cần lưu ý là nếu bạn không đặt các biện pháp bảo vệ và kiểm tra thích hợp trong mã của mình, thì bạn có thể thấy các điều kiện tương tranh bắt đầu tạo ra sự cố.
Các loại chủ đề
Có hai loại chủ đề riêng biệt. đó là
- Chủ đề cấp người dùng. Đây là những thứ chúng ta có thể tích cực chơi với mã của mình, v.v.
- Chủ đề cấp hạt nhân. Đây là những luồng cấp rất thấp hoạt động thay mặt cho hệ điều hành
đa luồng
Khi mọi người thường nói về bộ xử lý đa luồng, họ thường đề cập đến một bộ xử lý có thể chạy nhiều luồng đồng thời. Chúng thường có 2 hoặc nhiều luồng cạnh tranh tích cực về thời gian thực thi trong một lõi và khi một luồng bỏ cuộc hoặc dừng lại, lõi xử lý sẽ bắt đầu thực thi một luồng khác. Nó chuyển ngữ cảnh giữa các luồng này rất nhanh và tạo ấn tượng rằng máy tính đang chạy mọi thứ song song
Tạo một chủ đề đơn giản
Trước khi bắt đầu tạo một luồng trong Python, chúng ta nên xem qua hàm tạo của lớp Thread trong Python và xem những gì chúng ta cần truyền vào
## Python Thread class Constructor
def __init__[self, group=None, target=None, name=None, args=[], kwargs=None, verbose=None]:
Nó có năm tham số riêng biệt
- tập đoàn. một tham số đặc biệt được dành riêng cho phần mở rộng trong tương lai
- Mục tiêu. đối tượng có thể gọi được sẽ được gọi bởi phương thức chạy [], nếu Không thì sẽ không có gì được bắt đầu…
- Tên. Tên chủ đề của chúng tôi
- tranh luận. bộ đối số cho lệnh gọi đích. mặc định là
6
Code language: Python [python]from time import sleep, perf_counter
- kwargs. đối số từ khóa từ điển để gọi hàm tạo của lớp cơ sở
Điều quan trọng cần chú ý là tham số
7. Để bắt đầu một luồng đơn giản, chúng ta cần truyền cho nó một thứ gì đó để chạy. Hãy tạo một hàm đơn giản mà sau đó chúng ta sẽ sử dụng để tạo chuỗi đầu tiên của mình như vậyCode language: Python [python]
from time import sleep, perf_counter
Bản tóm tắt. trong hướng dẫn này, bạn sẽ học cách sử dụng mô-đun luồng Python để phát triển các ứng dụng đa luồng
Ứng dụng đơn luồng
Hãy bắt đầu với một chương trình đơn giản
Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Làm thế nào nó hoạt động
Đầu tiên, nhập các hàm
7 vàCode language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
8 từ mô-đunCode language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
9Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Code language: Python [python]
from time import sleep, perf_counter
Thứ hai, xác định chức năng mất một giây để hoàn thành
Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Thứ ba, lấy giá trị của bộ đếm hiệu suất bằng cách gọi hàm
8________số 8Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Thứ tư, gọi hàm
1 hai lầnCode language: Python [python]
start_time = perf_counter[]
0
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Code language: Python [python]
Thứ năm, lấy giá trị của bộ đếm hiệu suất bằng cách gọi hàm
8Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
2Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Cuối cùng, xuất thời gian cần thiết để hoàn thành việc chạy hàm
1 hai lầnCode language: Python [python]
start_time = perf_counter[]
4Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Đây là đầu ra
5Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Như bạn có thể mong đợi, chương trình mất khoảng hai giây để hoàn thành. Nếu bạn gọi hàm
1 10 lần, sẽ mất khoảng 10 giây để hoàn thànhCode language: Python [python]
start_time = perf_counter[]
Sơ đồ sau minh họa cách hoạt động của chương trình
Đầu tiên, hàm
1 thực thi và ngủ trong một giây. Sau đó, nó thực thi lần thứ hai và cũng ngủ thêm một giây nữa. Cuối cùng, chương trình hoàn thànhCode language: Python [python]
start_time = perf_counter[]
Khi hàm
1 gọi hàmCode language: Python [python]
start_time = perf_counter[]
7, CPU không hoạt động. Nói cách khác, CPU không làm gì cả, điều này không hiệu quả về mặt sử dụng tài nguyênCode language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Chương trình này có một tiến trình với một luồng duy nhất, được gọi là luồng chính. Vì chương trình chỉ có một luồng nên được gọi là chương trình đơn luồng
Sử dụng luồng Python để phát triển một ví dụ về chương trình đa luồng
Để tạo một chương trình đa luồng, bạn cần sử dụng mô-đun Python
8Code language: Python [python]
start_time = perf_counter[]
Đầu tiên, nhập lớp
9 từ mô-đunCode language: Python [python]
start_time = perf_counter[]
8Code language: Python [python]
start_time = perf_counter[]
3Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Thứ hai, tạo một luồng mới bằng cách khởi tạo một thể hiện của lớp
9Code language: Python [python]
start_time = perf_counter[]
5Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
02 chấp nhận nhiều tham số. Những cái chính làCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
03. chỉ định một chức năng [
Code language: Python [python]from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
04] để chạy trong chủ đề mới
Code language: Python [python]from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
05. chỉ định các đối số của hàm [______104]. Đối số
Code language: Python [python]from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
05 là một bộ
Code language: Python [python]from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Thứ ba, bắt đầu luồng bằng cách gọi phương thức
08 của thể hiệnCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
9Code language: Python [python]
start_time = perf_counter[]
0Code language: Python [python]
from time import sleep, perf_counter
Nếu bạn muốn đợi luồng hoàn thành trong luồng chính, bạn có thể gọi phương thức
20Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
1Code language: Python [python]
from time import sleep, perf_counter
Bằng cách gọi phương thức
20, luồng chính sẽ đợi luồng thứ hai hoàn thành trước khi kết thúcCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Chương trình sau minh họa cách sử dụng module
8Code language: Python [python]
start_time = perf_counter[]
2Code language: Python [python]
from time import sleep, perf_counter
Làm thế nào nó hoạt động. [và chúng tôi sẽ chỉ tập trung vào phần luồng]
Đầu tiên, tạo hai chủ đề mới
3Code language: Python [python]
from time import sleep, perf_counter
Thứ hai, bắt đầu cả hai luồng bằng cách gọi phương thức
08Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
4Code language: Python [python]
from time import sleep, perf_counter
Thứ ba, đợi cả hai chủ đề hoàn thành
5Code language: Python [python]
from time import sleep, perf_counter
Cuối cùng, hiển thị thời gian thực hiện
4Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
đầu ra
7
from time import sleep, perf_counter
Code language: Python [python]
Khi chương trình thực thi, nó sẽ có ba luồng. luồng chính được tạo bởi trình thông dịch Python và hai luồng được tạo bởi chương trình
Như được hiển thị rõ ràng từ đầu ra, chương trình mất một giây thay vì hai giây để hoàn thành
Sơ đồ sau đây cho thấy các luồng thực thi như thế nào
Truyền đối số cho chủ đề
Chương trình sau đây cho thấy cách truyền đối số cho hàm được gán cho luồng
8Code language: Python [python]
from time import sleep, perf_counter
Làm thế nào nó hoạt động
Đầu tiên, xác định một hàm
1 chấp nhận một đối sốCode language: Python [python]
start_time = perf_counter[]
9Code language: Python [python]
from time import sleep, perf_counter
Thứ hai, tạo 10 chủ đề mới và chuyển id cho mỗi chủ đề. Danh sách
25 được sử dụng để theo dõi tất cả các chủ đề mới được tạoCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
0Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Lưu ý rằng nếu bạn gọi phương thức
20 bên trong vòng lặp, chương trình sẽ đợi luồng đầu tiên hoàn thành trước khi bắt đầu luồng tiếp theoCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Thứ ba, đợi tất cả các luồng hoàn thành bằng cách gọi phương thức
20Code language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
1Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Sau đây là kết quả đầu ra của chương trình
2Code language: Python [python]
def task[]: print['Starting a task...'] sleep[1] print['done']
Nó chỉ mất 1. 05 giây để hoàn thành
Chú ý chương trình không thực hiện luồng theo thứ tự từ 1 đến 10
Khi nào nên sử dụng luồng Python
Như đã giới thiệu trong phần hướng dẫn process và thread, có 2 nhiệm vụ chính
- Các tác vụ liên quan đến I/O – thời gian dành cho I/O nhiều hơn đáng kể so với thời gian dành cho tính toán
- Các tác vụ liên quan đến CPU – thời gian dành cho tính toán cao hơn đáng kể so với thời gian chờ I/O
Luồng Python được tối ưu hóa cho các tác vụ ràng buộc I/O. Ví dụ: yêu cầu tài nguyên từ xa, kết nối máy chủ cơ sở dữ liệu hoặc đọc và ghi tệp
Một ví dụ luồng Python thực tế
Giả sử rằng bạn có một danh sách các tệp văn bản trong một thư mục e. g. ,
28. Và bạn muốn thay thế một văn bản bằng một văn bản mới trong tất cả các tệpCode language: Python [python]
from time import sleep, perf_counter def task[]: print['Starting a task...'] sleep[1] print['done'] start_time = perf_counter[] task[] task[] end_time = perf_counter[] print[f'It took {end_time- start_time: 0.2f} second[s] to complete.']
Chương trình đơn luồng sau đây cho biết cách thay thế chuỗi con bằng chuỗi con mới trong tệp văn bản