Bạn có thể print[] ra thiết bị xuất chuẩn từ các tiến trình con bằng cách đặt đối số "flush" thành True hoặc bằng cách sử dụng phương thức bắt đầu 'fork'
Trong hướng dẫn này, bạn sẽ khám phá cách in[] từ các tiến trình con trong Python
Bắt đầu nào
Mục lục
Sự cố với print[] trong Quy trình con
In ra tiêu chuẩn [stdout] với chức năng print[] tích hợp có thể không hoạt động thuộc tính từ các quy trình con
Ví dụ: bạn có thể in thông báo đầu ra cho người dùng hoặc thông báo gỡ lỗi từ tiến trình con và chúng có thể không bao giờ xuất hiện hoặc chỉ có thể xuất hiện khi tiến trình con kết thúc
1
2
3
.. .
# báo cáo một tin nhắn từ một tiến trình con
print['Xin chào từ tiến trình con']
Bạn có vẫn đề gì không?
Hãy cho tôi biết trong các ý kiến dưới đây
Đây là một tình huống rất phổ biến và nguyên nhân được hiểu rõ và dễ giải quyết
Tiếp theo, hãy xem chính xác lý do tại sao sự cố này xảy ra
Chạy các vòng lặp của bạn bằng cách sử dụng tất cả các CPU, tải xuống cuốn sách MIỄN PHÍ của tôi để tìm hiểu cách thực hiện
Tại sao print[] không hoạt động từ các tiến trình con
Đây là một chức năng tích hợp để hiển thị tin nhắn trên
Khi bạn gọi print[] từ một tiến trình con được tạo bằng phương thức bắt đầu ‘spawn‘, thông báo sẽ không xuất hiện
Điều này là do các tin nhắn được lưu vào bộ đệm theo mặc định và bộ đệm không bị xóa theo mặc định sau mỗi tin nhắn. Điều này không giống như quy trình chính tương tác và sẽ xóa thông báo sau mỗi dòng, e. g. dòng đệm
Khi tương tác, luồng xuất chuẩn được đệm theo dòng. Mặt khác, nó được chặn vào bộ đệm giống như các tệp văn bản thông thường
— sys — Các tham số và chức năng dành riêng cho hệ thống
Thay vào đó, các thông báo trong bộ đệm chỉ thỉnh thoảng bị xóa, chẳng hạn như khi quá trình con kết thúc và bộ đệm được thu gom rác
Tiếp theo, hãy xem cách chúng ta có thể làm cho hàm print[] hoạt động như mong đợi từ các tiến trình con
Bị bối rối bởi API mô-đun đa xử lý?
Tải xuống bảng cheat PDF MIỄN PHÍ của tôi
Cách in từ các tiến trình con
Có hai kỹ thuật bạn có thể sử dụng để làm cho các thông báo print[] xuất hiện ngay lập tức khi được gọi từ một tiến trình con
họ đang
- tuôn ra thiết bị xuất chuẩn
- Sử dụng phương thức bắt đầu 'fork'
Xả đầu ra tiêu chuẩn
Bạn có thể tự động xóa thiết bị xuất chuẩn với mỗi lệnh gọi print[]
Điều này có thể đạt được bằng cách đặt đối số 'tuôn ra' thành True
Ví dụ
1
2
3
.. .
# báo cáo một tin nhắn từ một tiến trình con
print['Xin chào từ tiến trình con', flush=True]
Một cách tiếp cận khác là gọi hàm flush[] trên sys. đối tượng stdout trực tiếp
Ví dụ
1
2
3
4
5
.. .
# báo cáo một tin nhắn từ một tiến trình con
print['Xin chào từ tiến trình con']
# tuôn ra đầu ra
sys. thiết bị xuất chuẩn. xả[]
Sử dụng phương pháp Fork Start
Có ba kỹ thuật chính để bắt đầu một tiến trình con trong Python
họ đang
- Đẻ trứng
- Cái nĩa
- ngã ba máy chủ
Trên Windows và macOS, kỹ thuật 'spawn' được sử dụng theo mặc định
Ngoài ra, trên một nền tảng khác, bạn có thể chọn sử dụng phương thức bắt đầu 'sinh sản'
Ví dụ
1
2
3
.. .
# đặt phương thức bắt đầu để sinh sản
set_start_method['spawn']
Sự cố với hàm print[] chỉ xảy ra khi sử dụng phương thức bắt đầu ‘spawn‘
Bạn có thể thay đổi phương thức bắt đầu thành 'fork', điều này sẽ khiến print[] hoạt động như mong đợi
Lưu ý, phương thức bắt đầu 'fork' không được hỗ trợ trên Windows tại thời điểm viết bài
Bạn có thể đặt phương thức bắt đầu thông qua
Ví dụ
1
2
3
.. .
# đặt phương thức bắt đầu thành fork
set_start_method['fork']
Bạn có thể tìm hiểu thêm về các phương pháp bắt đầu quy trình trong hướng dẫn
- Phương thức bắt đầu đa xử lý
Bây giờ chúng ta đã biết cách sửa hàm print[] từ các tiến trình con, hãy xem một số ví dụ đã hoạt động
Khóa học đa xử lý Python miễn phí
Tải xuống bảng cheat API đa xử lý của tôi và như một phần thưởng, bạn sẽ nhận được quyền truy cập MIỄN PHÍ vào khóa học email 7 ngày của tôi
Khám phá cách sử dụng mô-đun đa xử lý Python, bao gồm cách tạo và bắt đầu các tiến trình con cũng như cách sử dụng khóa mutex và semaphores
Tìm hiểu thêm
Ví dụ về bản in bị hỏng từ quy trình con
Trước khi khám phá cách làm cho hàm print[] hoạt động như mong đợi từ các tiến trình con, hãy chứng minh vấn đề in từ các tiến trình con
Trong ví dụ này, chúng tôi sẽ bắt đầu một tiến trình con để thực thi một chức năng tùy chỉnh để in một thông báo, sau đó chặn trong một giây. Tiến trình chính sẽ bắt đầu tiến trình con, sau đó đợi nó kết thúc trước khi tự in thông báo
Thay vì thông báo từ tiến trình con xuất hiện ngay sau khi tiến trình con được bắt đầu, như chúng ta có thể mong đợi, thay vào đó, thông báo từ tiến trình con không xuất hiện cho đến khi tiến trình con kết thúc
Đầu tiên, hãy định nghĩa một hàm sẽ được thực thi trong một tiến trình con
Chức năng này sẽ báo một thông báo sau đó ngủ một giây trước khi thoát
Hàm task[] bên dưới thực hiện điều này
1
2
3
4
5
6
# chức năng được thực thi trong một tiến trình con
def nhiệm vụ[].
# báo cáo thư
print['Xin chào từ quy trình con']
# khối trong giây lát
ngủ[1]
Tiếp theo, trong quy trình chính, chúng tôi sẽ đặt phương thức bắt đầu thành 'spawn', để đảm bảo hàm print[] không hoạt động như mong đợi
1
2
3
.. .
# đặt phương thức bắt đầu để sinh sản
set_start_method['spawn']
Tiếp theo, chúng tôi sẽ in một thông báo từ quy trình chính, thông báo này sẽ xuất hiện ngay lập tức
1
2
3
.. .
# báo cáo một tin nhắn
in['Xin chào từ quy trình chính']
Sau đó chúng ta sẽ cấu hình một bộ xử lý đa năng mới. Phiên bản xử lý để thực thi chức năng tùy chỉnh của chúng tôi, bắt đầu tiến trình con, sau đó đợi nó kết thúc
1
2
3
4
5
6
7
.. .
# tạo và cấu hình tiến trình con
quy trình = Quy trình[mục tiêu=task]
# bắt đầu tiến trình con
quy trình. bắt đầu[]
# đợi tiến trình con kết thúc
quy trình. tham gia[]
Cuối cùng, quá trình chính sẽ báo cáo một thông báo khác
1
2
3
.. .
# báo cáo một tin nhắn khác
in['Xin chào lại từ quy trình chính']
Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Trăn Siêu Nhanh. com
# ví dụ về quá trình in từ tiến trình con không hoạt động
từ thời gian nhập ngủ
từ đa xử lý nhập Quy trình
từ đa xử lý nhập set_start_method
# chức năng được thực thi trong một tiến trình con
def nhiệm vụ[].
# báo cáo thư
print['Xin chào từ quy trình con']
# khối trong giây lát
ngủ[1]
# điểm vào được bảo vệ
if __name__ == '__main__'.
# đặt phương thức bắt đầu để xuất hiện
set_start_method['spawn']
# báo cáo thư
in['Xin chào từ quy trình chính']
# tạo và định cấu hình quy trình con
quy trình = Quy trình[target=task]
# bắt đầu tiến trình con
quy trình. bắt đầu[]
# đợi quá trình con kết thúc
quy trình. tham gia[]
# báo cáo thư khác
in['Xin chào lại từ quy trình chính']
Chạy ví dụ đầu tiên sẽ in một thông báo từ quy trình chính, thông báo này sẽ xuất hiện ngay lập tức
Tiếp theo, quy trình con được tạo và bắt đầu và quy trình chính sẽ chặn và đợi nó kết thúc
Tiến trình con gọi print[], nhưng thông báo không xuất hiện. Sau đó, nó chặn trong một giây, sau đó chấm dứt
Cuối cùng, thông báo từ tiến trình con xuất hiện sau khi tiến trình con kết thúc
Quá trình chính sau đó báo cáo một thông báo thứ hai, thông báo này xuất hiện ngay lập tức
Điều này nhấn mạnh rằng việc in từ một quy trình con được tạo bằng phương thức bắt đầu 'spawn' không hoạt động như chúng ta mong đợi
1
2
3
Xin chào từ quy trình chính
Xin chào từ tiến trình con
Xin chào một lần nữa từ quá trình chính
Tiếp theo, hãy xem cách chúng ta có thể khắc phục hành vi của câu lệnh print[] bằng cách sử dụng phương thức bắt đầu 'fork'
Bị choáng ngợp bởi các API đồng thời python?
Tìm sự giải thoát, tải xuống Bản đồ tư duy đồng thời Python MIỄN PHÍ của tôi
Đã sửa lỗi in bằng phương pháp khởi động ngã ba
Chúng ta có thể khám phá cách làm cho print[] từ các tiến trình con hoạt động như mong đợi bằng cách thay đổi phương thức start
Trong ví dụ này, chúng tôi sẽ cập nhật ví dụ từ phần trước để sử dụng phương thức bắt đầu 'fork' thay vì phương thức bắt đầu 'spawn'
Ví dụ
1
2
3
.. .
# đặt phương thức bắt đầu thành fork
set_start_method['fork']
Và đó là nó
Ví dụ đầy đủ được liệt kê dưới đây
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Trăn Siêu Nhanh. com
# ví dụ về quá trình in từ tiến trình con không hoạt động
từ thời gian nhập ngủ
từ đa xử lý nhập Quy trình
từ đa xử lý nhập set_start_method
# chức năng được thực thi trong một tiến trình con
def nhiệm vụ[].
# báo cáo thư
print['Xin chào từ quy trình con']
# khối trong giây lát
ngủ[1]
# điểm vào được bảo vệ
if __name__ == '__main__'.
# đặt phương thức bắt đầu thành fork
set_start_method['fork']
# báo cáo thư
in['Xin chào từ quy trình chính']
# tạo và định cấu hình quy trình con
quy trình = Quy trình[target=task]
# bắt đầu tiến trình con
quy trình. bắt đầu[]
# đợi quá trình con kết thúc
quy trình. tham gia[]
# báo cáo thư khác
in['Xin chào lại từ quy trình chính']
Chạy ví dụ đầu tiên sẽ in một thông báo từ quy trình chính, thông báo này sẽ xuất hiện ngay lập tức
Tiếp theo, quy trình con được tạo và bắt đầu và quy trình chính sẽ chặn và đợi nó kết thúc
Quá trình con gọi print[] và thông báo xuất hiện ngay lập tức. Sau đó, nó chặn trong một giây, sau đó chấm dứt
Quá trình chính sau đó báo cáo một thông báo thứ hai, thông báo này xuất hiện ngay lập tức
Điều này nhấn mạnh rằng việc thay đổi phương thức start thành fork sẽ khiến quá trình in từ tiến trình con hoạt động như mong đợi
Lưu ý, phương thức khởi động ngã ba không được hỗ trợ trên Windows
1
2
3
Xin chào từ quy trình chính
Xin chào từ tiến trình con
Xin chào một lần nữa từ quá trình chính
Tiếp theo, hãy xem cách chúng tôi có thể khắc phục lỗi in từ một tiến trình con bằng cách xóa từng thông báo
Sửa lỗi Print With flush=True
Chúng ta có thể khám phá cách khắc phục lỗi in từ các tiến trình con bằng cách xóa thiết bị xuất chuẩn mỗi khi hàm print[] được gọi
Trong ví dụ này, chúng tôi sẽ cập nhật ví dụ bị hỏng ở trên và thay đổi câu lệnh print[] để thiết bị xuất chuẩn được xóa trực tiếp
Điều này có thể đạt được bằng cách đặt đối số 'tuôn ra' thành True
Ví dụ
1
2
3
.. .
# báo cáo một tin nhắn
print['Xin chào từ tiến trình con', flush=True]
Hàm task[] hoàn chỉnh với thay đổi này được liệt kê bên dưới
1
2
3
4
5
6
# chức năng được thực thi trong một tiến trình con
def nhiệm vụ[].
# báo cáo thư
print['Xin chào từ quy trình con', flush=True]
# khối trong giây lát
ngủ[1]
Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Trăn Siêu Nhanh. com
# ví dụ về in từ tiến trình con với đầu ra flushed
từ thời gian nhập ngủ
từ đa xử lý nhập Quy trình
từ đa xử lý nhập set_start_method
# chức năng được thực thi trong một tiến trình con
def nhiệm vụ[].
# báo cáo thư
print['Xin chào từ quy trình con', flush=True]
# khối trong giây lát
ngủ[1]
# điểm vào được bảo vệ
if __name__ == '__main__'.
# đặt phương thức bắt đầu để xuất hiện
set_start_method['spawn']
# báo cáo thư
in['Xin chào từ quy trình chính']
# tạo và định cấu hình quy trình con
quy trình = Quy trình[target=task]
# bắt đầu tiến trình con
quy trình. bắt đầu[]
# đợi quá trình con kết thúc
quy trình. tham gia[]
# báo cáo thư khác
in['Xin chào lại từ quy trình chính']
Chạy ví dụ đầu tiên sẽ in một thông báo từ quy trình chính, thông báo này sẽ xuất hiện ngay lập tức
Tiếp theo, quy trình con được tạo và bắt đầu và quy trình chính sẽ chặn và đợi nó kết thúc
Quá trình con gọi print[] và thông báo xuất hiện ngay lập tức. Sau đó, nó chặn trong một giây, sau đó chấm dứt
Quá trình chính sau đó báo cáo một thông báo thứ hai, thông báo này xuất hiện ngay lập tức
Điểm nổi bật này là việc xóa luồng đầu ra tiêu chuẩn một cách rõ ràng sau khi gọi print[] sẽ khiến các thông báo được in xuất hiện ngay lập tức như chúng ta mong đợi