Đa quy trình Python

Phân luồng chỉ là một trong nhiều cách có thể xây dựng các chương trình đồng thời. Trong bài viết này, chúng ta sẽ xem xét phân luồng và một vài chiến lược khác để xây dựng các chương trình đồng thời trong Python, cũng như thảo luận về cách mỗi chiến lược phù hợp trong các tình huống khác nhau

Chia sẻ

Chia sẻ

Đa quy trình Python

Phân luồng chỉ là một trong nhiều cách có thể xây dựng các chương trình đồng thời. Trong bài viết này, chúng ta sẽ xem xét phân luồng và một vài chiến lược khác để xây dựng các chương trình đồng thời trong Python, cũng như thảo luận về cách mỗi chiến lược phù hợp trong các tình huống khác nhau

Đa quy trình Python

Bởi Marcus McCurdy

Chuyên gia đã được xác minh  về Kỹ thuật

Marcus là một lập trình viên tài năng và xuất sắc trong lĩnh vực phát triển back-end. Tuy nhiên, anh cảm thấy thoải mái với tư cách là một full stack developer

Trong kỷ nguyên Dữ liệu lớn, Python trở thành ngôn ngữ được tìm kiếm nhiều nhất. Trong bài viết này, chúng ta hãy tập trung vào một khía cạnh cụ thể của Python khiến nó trở thành một trong những ngôn ngữ lập trình mạnh mẽ nhất - Đa xử lý

Bây giờ trước khi chúng ta đi sâu vào vấn đề cốt lõi của Đa xử lý, tôi khuyên bạn nên đọc bài viết trước của tôi về Phân luồng trong Python, vì nó có thể cung cấp ngữ cảnh tốt hơn cho bài viết hiện tại

Đa xử lý là gì-

Giả sử bạn là một học sinh tiểu học được giao nhiệm vụ khó nhằn là nhân 1200 cặp số như bài tập về nhà của bạn. Giả sử bạn có khả năng nhân một cặp số trong vòng 3 giây. Sau đó, tổng cộng, phải mất 1200 * 3 = 3600 giây, tức là 1 giờ để giải toàn bộ bài tập. Nhưng bạn phải xem chương trình truyền hình yêu thích của mình trong 20 phút nữa

Bạn sẽ làm gì? . Vì vậy, bạn sẽ nhận được 250 nhiệm vụ nhân trên đĩa của mình, bạn sẽ hoàn thành nhiệm vụ này trong 250*3 = 750 giây, tức là 15 phút. Như vậy, bạn cùng với 3 người bạn khác của mình sẽ hoàn thành nhiệm vụ trong 15 phút, bạn có 5 phút để ăn nhẹ và ngồi xem chương trình truyền hình của mình. Nhiệm vụ chỉ mất 15 phút khi 4 bạn làm việc cùng nhau, nếu không thì sẽ mất 1 giờ

Đây là hệ tư tưởng cơ bản của Multi-Processing. Nếu bạn có một thuật toán có thể chia thành các công nhân (bộ xử lý) khác nhau, thì bạn có thể tăng tốc chương trình. Các máy ngày nay có 4,8 và 16 lõi, sau đó có thể được triển khai song song

Đa xử lý trong Khoa học dữ liệu-

Đa xử lý có hai ứng dụng quan trọng trong Khoa học dữ liệu

1. Quy trình đầu vào-đầu ra-

Bất kỳ đường ống sử dụng nhiều dữ liệu nào cũng có các quy trình đầu vào, đầu ra trong đó hàng triệu byte dữ liệu chảy khắp hệ thống. Nói chung, quá trình đọc (nhập) dữ liệu sẽ không mất nhiều thời gian nhưng quá trình ghi dữ liệu vào Kho dữ liệu mất nhiều thời gian. Quá trình viết có thể được thực hiện song song, tiết kiệm một lượng lớn thời gian

Đa quy trình Python

Đa quy trình Python

2. Mô hình đào tạo

Mặc dù không phải tất cả các mô hình đều có thể được đào tạo song song, nhưng một số mô hình có các đặc điểm vốn có cho phép chúng được đào tạo bằng xử lý song song. Ví dụ: thuật toán Rừng ngẫu nhiên triển khai nhiều cây Quyết định để đưa ra quyết định tích lũy. Những cây này có thể được xây dựng song song. Trên thực tế, API sklearn đi kèm với một tham số có tên là n_jobs, cung cấp tùy chọn sử dụng nhiều công nhân

Đa xử lý trong Python sử dụng lớp Process-

Bây giờ chúng ta hãy bắt tay vào thư viện đa xử lý trong Python

Hãy xem đoạn mã sau

Mã Python

Đoạn mã trên rất đơn giản. Hàm sleep_man ngủ trong một giây và chúng tôi gọi hàm hai lần. Chúng tôi ghi lại thời gian thực hiện cho hai lệnh gọi hàm và in kết quả. Đầu ra như hình bên dưới

Starting to sleep
Done sleeping
Starting to sleep
Done sleeping
Done in 2.0037 seconds

Điều này được mong đợi khi chúng ta gọi hàm hai lần và ghi lại thời gian. Dòng chảy được thể hiện trong sơ đồ dưới đây

Đa quy trình Python

Bây giờ chúng ta hãy kết hợp Đa xử lý vào mã

import multiprocessing
import time

def sleepy_man():
    print('Starting to sleep')
    time.sleep(1)
    print('Done sleeping')

tic = time.time()
p1 =  multiprocessing.Process(target= sleepy_man)
p2 =  multiprocessing.Process(target= sleepy_man)
p1.start()
p2.start()
toc = time.time()

print('Done in {:.4f} seconds'.format(toc-tic))

đây đa xử lý. Quy trình (mục tiêu = buồn ngủ) xác định một phiên bản đa quy trình. Chúng tôi chuyển chức năng bắt buộc để được thực thi, Sleepy_man, làm đối số. Chúng tôi kích hoạt hai trường hợp bằng p1. bắt đầu()

Đầu ra như sau-

Done in 0.0023 seconds
Starting to sleep
Starting to sleep
Done sleeping
Done sleeping

Bây giờ chú ý một điều. Câu lệnh in nhật ký thời gian được thực hiện trước. Điều này là do cùng với các phiên bản đa quy trình được kích hoạt cho hàm sleep_man, mã chính của hàm được thực thi song song một cách riêng biệt. Sơ đồ dòng chảy được đưa ra dưới đây sẽ làm cho mọi thứ rõ ràng

Đa quy trình Python

Để thực thi phần còn lại của chương trình sau khi các hàm đa tiến trình được thực thi, chúng ta cần thực thi hàm join()

import multiprocessing
import time

def sleepy_man():
    print('Starting to sleep')
    time.sleep(1)
    print('Done sleeping')

tic = time.time()
p1 =  multiprocessing.Process(target= sleepy_man)
p2 =  multiprocessing.Process(target= sleepy_man)
p1.start()
p2.start()
p1.join()
p2.join()
toc = time.time()

print('Done in {:.4f} seconds'.format(toc-tic))

Bây giờ phần còn lại của khối mã sẽ chỉ được thực thi sau khi hoàn thành các tác vụ đa xử lý. Đầu ra được hiển thị dưới đây

Starting to sleep
Starting to sleep
Done sleeping
Done sleeping
Done in 1.0090 seconds

Sơ đồ dòng chảy được hiển thị dưới đây

Đa quy trình Python

Vì hai chức năng ngủ được thực thi song song, nên chức năng cùng nhau mất khoảng 1 giây

Chúng tôi có thể xác định bất kỳ số lượng phiên bản đa xử lý nào. Nhìn vào mã dưới đây. Nó xác định 10 trường hợp đa xử lý khác nhau bằng cách sử dụng vòng lặp for

import multiprocessing
import time

def sleepy_man():
    print('Starting to sleep')
    time.sleep(1)
    print('Done sleeping')

tic = time.time()

process_list = []
for i in range(10):
    p =  multiprocessing.Process(target= sleepy_man)
    p.start()
    process_list.append(p)

for process in process_list:
    process.join()

toc = time.time()

print('Done in {:.4f} seconds'.format(toc-tic))

Đầu ra cho mã trên là như hình dưới đây

Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done in 1.0117 seconds

Ở đây, mười lần thực thi chức năng được xử lý song song và do đó, toàn bộ chương trình chỉ mất một giây. Bây giờ máy của tôi không có 10 bộ xử lý. Khi chúng tôi xác định nhiều quy trình hơn máy của mình, thư viện đa xử lý có logic để lên lịch cho các công việc. Vì vậy, bạn không phải lo lắng về nó

Chúng ta cũng có thể truyền đối số cho hàm Process bằng cách sử dụng args

________số 8_______

Đầu ra cho mã trên là như hình dưới đây

Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Starting to sleep
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done sleeping
Done in 2.0161 seconds

Vì chúng ta đã truyền một đối số nên hàm sleep_man ngủ trong 2 giây thay vì 1 giây

Đa xử lý trong Python sử dụng lớp Pool-

Trong đoạn mã cuối cùng, chúng tôi đã thực hiện 10 quy trình khác nhau bằng cách sử dụng vòng lặp for. Thay vào đó, chúng ta có thể sử dụng phương thức Pool để làm điều tương tự

import multiprocessing
import time
0

đa xử lý. Nhóm (5) xác định số lượng công nhân. Ở đây chúng tôi xác định số là 5. hồ bơi. map() là phương thức kích hoạt thực thi chức năng. Chúng tôi gọi hồ bơi. bản đồ (sleepy_man, phạm vi (1,11)). Ở đây, Sleepy_man  là hàm sẽ được gọi với các tham số cho các lần thực thi hàm được xác định bởi phạm vi(1,11)  (thường là một danh sách được chuyển). Đầu ra như sau-

import multiprocessing
import time
1

Lớp nhóm là một cách tốt hơn để triển khai Đa xử lý vì nó phân phối các tác vụ cho các bộ xử lý có sẵn bằng cách sử dụng lịch trình Nhập trước xuất trước. Nó gần giống với kiến ​​trúc map-reduce - về bản chất, nó ánh xạ đầu vào tới các bộ xử lý khác nhau và thu thập đầu ra từ tất cả các bộ xử lý dưới dạng danh sách. Các quy trình đang thực thi được lưu trữ trong bộ nhớ và các quy trình không thực thi khác được lưu trữ ngoài bộ nhớ

Đa quy trình Python

Trong khi ở lớp Quy trình, tất cả các quy trình được thực thi trong bộ nhớ và thực thi theo lịch trình bằng chính sách FIFO

So sánh hiệu suất thời gian để tính số hoàn hảo-

Cho đến nay, chúng tôi đã thử nghiệm với các chức năng đa xử lý trên các chức năng ngủ. Bây giờ chúng ta hãy thực hiện một hàm kiểm tra xem một số có phải là Số hoàn hảo hay không. Dành cho những ai chưa biết, Một số là số hoàn hảo nếu tổng các ước dương của nó bằng chính số đó. Chúng tôi sẽ liệt kê các Số hoàn hảo nhỏ hơn hoặc bằng 100000. Chúng tôi sẽ thực hiện nó theo 3 cách- Sử dụng vòng lặp for thông thường, sử dụng đa xử lý. Quy trình () và đa quy trình. Hồ bơi().

Sử dụng một vòng lặp thông thường-

import multiprocessing
import time
2

Đầu ra cho chương trình trên được hiển thị bên dưới

import multiprocessing
import time
3

Sử dụng một lớp Process-

import multiprocessing
import time
4

Đầu ra cho chương trình trên được hiển thị bên dưới

import multiprocessing
import time
5

Như bạn có thể thấy, chúng tôi đã đạt được 44. Giảm 4% thời gian khi chúng tôi triển khai Đa xử lý bằng cách sử dụng lớp Quy trình, thay vì vòng lặp for thông thường

Sử dụng lớp Pool-

import multiprocessing
import time
6

Đầu ra cho chương trình trên được hiển thị bên dưới

import multiprocessing
import time
7

Như bạn có thể thấy, so với vòng lặp for thông thường, chúng tôi đã đạt được 71. Giảm 3% thời gian tính toán và so với lớp Quy trình, chúng tôi đạt được 48. Giảm 4% thời gian tính toán

Vì vậy, rõ ràng là bằng cách triển khai một phương thức phù hợp từ thư viện đa xử lý, chúng ta có thể giảm đáng kể thời gian tính toán

Phương tiện hiển thị trong bài viết này không thuộc sở hữu của Analytics Vidhya và được sử dụng theo quyết định của Tác giả.  

Python có hỗ trợ đa xử lý không?

Trong Python, đa xử lý có thể được triển khai bằng cách sử dụng mô-đun đa xử lý (hoặc đồng thời. tương lai. ProcessPoolExecutor ) có thể được sử dụng để tạo ra nhiều quy trình hệ điều hành .

Đa xử lý có nhanh hơn Python không?

Vì vậy, đa xử lý sẽ nhanh hơn khi chương trình được giới hạn bởi CPU . Trong trường hợp có nhiều I/O trong chương trình của bạn, phân luồng có thể hiệu quả hơn vì hầu hết thời gian, chương trình của bạn đang đợi I/O hoàn thành. Tuy nhiên, đa xử lý thường hiệu quả hơn vì nó chạy đồng thời.

Có bao nhiêu quy trình nên chạy đa xử lý Python?

Nếu chúng ta đang sử dụng trình quản lý ngữ cảnh để tạo nhóm quy trình để nó tự động tắt, thì bạn có thể định cấu hình số lượng quy trình theo cách tương tự. Số lượng công nhân phải nhỏ hơn hoặc bằng 61 nếu Windows là hệ điều hành của bạn .