Hướng dẫn how do processes work in python? - các quy trình hoạt động như thế nào trong python?

Hướng dẫn dành cho người mới bắt đầu để lập trình song song

Cạnh tranh trong Kaggle, hiểu Amazon từ cuộc thi không gian, tôi đã bắt đầu định thời các phần khác nhau trong mã của mình để xem liệu tôi có thể tăng tốc mọi thứ không. Tốc độ là rất quan trọng trong Kaggle. Xếp hạng tốt thường đòi hỏi phải thử hàng trăm kết hợp kiến ​​trúc và siêu tham số. Cạo 10 giây cho một kỷ nguyên kéo dài 1 phút là một chiến thắng lớn.

Thật ngạc nhiên, tôi thấy tăng cường dữ liệu là nút cổ chai lớn nhất của tôi. Các phương pháp tôi đã sử dụng - xoay, lật, phóng to và cây trồng - dựa vào Numpy và chạy trên CPU. Numpy sử dụng xử lý song song trong một số trường hợp và các trình tải dữ liệu Pytorch cũng làm như vậy, nhưng tôi đã chạy 3 thí nghiệm 5 cùng một lúc và mỗi thử nghiệm đang thực hiện việc tăng cường. Điều này có vẻ không hiệu quả và tôi tò mò muốn xem liệu tôi có thể tăng tốc mọi thứ bằng cách xử lý song song hay không.

Xử lý song song là gì?

Về cơ bản làm hai việc cùng một lúc, đồng thời chạy mã trên các CPU khác nhau hoặc mã chạy trên cùng một CPU và đạt được tốc độ tăng tốc bằng cách tận dụng các chu kỳ CPU lãng phí .

Ví dụ, đây là một chương trình bình thường của người Viking. Nó tải xuống một danh sách các URL mỗi lần bằng một luồng.

Đây là cùng một chương trình sử dụng 2 chủ đề. Nó phân chia các URL giữa các luồng cho chúng ta tốc độ gần 2 lần.

Nếu bạn tò mò làm thế nào để tạo ra các biểu đồ này và những gì chúng có nghĩa là bạn có thể tìm thấy mã ở đây, nhưng để tóm tắt ngắn gọn:

  1. Thêm bộ hẹn giờ bên trong chức năng của bạn và trả lại thời gian bắt đầu và dừng
URLS = [url1, url2, url3, ...]def download(url, base):
start = time.time() - base
resp = urlopen(url)
stop = time.time() - base
return start,stop

2. Để trực quan hóa một luồng duy nhất, hãy chạy chức năng của bạn nhiều lần và lưu trữ thời gian bắt đầu và dừng

results = [download(url, 1) for url in URLS]

3. Chuyển đổi mảng kết quả của [bắt đầu, dừng] lần và vẽ biểu đồ thanh

def visualize_runtimes(results):
start,stop = np.array(results).T
plt.barh(range(len(start)), stop-start, left=start)
plt.grid(axis=’x’)
plt.ylabel("Tasks")
plt.xlabel("Seconds")

Biểu đồ cho nhiều luồng có thể được tạo theo cùng một cách. Các phương pháp trong thư viện đồng thời Python, trả về một loạt các kết quả.

Quy trình vs luồng

Một quy trình là một thể hiện của chương trình (ví dụ: máy tính xách tay Jupyter, trình thông dịch Python). Các quy trình sinh sản các luồng (quy trình phụ) để xử lý các nhiệm vụ phụ như đọc tổ hợp phím, tải các trang HTML, lưu tệp. Các chủ đề sống bên trong các quy trình và chia sẻ cùng một không gian bộ nhớ.process is an instance of program (e.g. Jupyter notebook, Python interpreter). Processes spawn threads (sub-processes) to handle subtasks like reading keystrokes, loading HTML pages, saving files. Threads live inside processes and share the same memory space.

Ví dụ: Microsoft Wordwhen bạn mở Word, bạn tạo một quy trình. Khi bạn bắt đầu gõ, quá trình sinh ra các chủ đề: một để đọc phím phím, một để hiển thị văn bản, một để tự động tự động tệp của bạn và một cái khác để làm nổi bật các lỗi chính tả. Bằng cách sinh sản nhiều luồng, Microsoft tận dụng thời gian CPU nhàn rỗi (chờ đợi phím hoặc tệp để tải) và giúp bạn làm việc hiệu quả hơn.
When you open Word, you create a process. When you start typing, the process spawns threads: one to read keystrokes, another to display text, one to autosave your file, and yet another to highlight spelling mistakes. By spawning multiple threads, Microsoft takes advantage of idle CPU time (waiting for keystrokes or files to load) and makes you more productive.

Quá trình

  • Được tạo bởi hệ điều hành để chạy các chương trình
  • Các quy trình có thể có nhiều luồng
  • Hai quy trình có thể thực thi mã đồng thời trong cùng một chương trình Python
  • Các quy trình có chi phí cao hơn các luồng vì các quy trình mở và đóng mất nhiều thời gian hơn
  • Chia sẻ thông tin giữa các quy trình chậm hơn so với chia sẻ giữa các luồng vì các quy trình không chia sẻ không gian bộ nhớ. Trong Python, họ chia sẻ thông tin bằng các cấu trúc dữ liệu như các mảng yêu cầu thời gian IO.

Chủ đề

  • Các chủ đề giống như các quy trình nhỏ sống trong một quá trình
  • Họ chia sẻ không gian bộ nhớ và đọc và ghi hiệu quả vào cùng một biến
  • Hai luồng không thể thực thi mã đồng thời trong cùng một chương trình Python (mặc dù có cách giải quyết*)

CPU vs Core

CPU, hoặc bộ xử lý, quản lý công việc tính toán cơ bản của máy tính. CPU có một hoặc nhiều lõi, cho phép CPU thực thi đồng thời mã.CPU, or processor, manages the fundamental computational work of the computer. CPUs have one or more cores, allowing the CPU to execute code simultaneously.

Với một lõi duy nhất, không có tốc độ tăng tốc cho các tác vụ chuyên sâu CPU (ví dụ: các vòng lặp, số học). HĐH chuyển qua lại giữa các tác vụ thực hiện mỗi tác phẩm một chút một lần. Đây là lý do tại sao đối với các hoạt động nhỏ (ví dụ: tải xuống một vài hình ảnh), đa nhiệm đôi khi có thể làm tổn thương hiệu suất của bạn. Có chi phí liên quan đến việc khởi động và duy trì nhiều nhiệm vụ.

Vấn đề Python sườn Gil

CPython (triển khai Python tiêu chuẩn) có một thứ gọi là GIL (khóa phiên dịch toàn cầu), ngăn hai luồng thực thi đồng thời trong cùng một chương trình. Một số người buồn bã vì điều này, trong khi những người khác bảo vệ nó một cách quyết liệt. Tuy nhiên, có các cách giải quyết và các thư viện như Numpy bỏ qua giới hạn này bằng cách chạy mã bên ngoài trong C.

Khi nào nên sử dụng Chủ đề so với các quy trình?

  • Các quá trình tăng tốc các hoạt động Python chuyên sâu CPU vì chúng được hưởng lợi từ nhiều lõi và tránh Gil. speed up Python operations that are CPU intensive because they benefit from multiple cores and avoid the GIL.
  • Chủ đề là tốt nhất cho các tác vụ hoặc tác vụ IO liên quan đến các hệ thống bên ngoài vì các chủ đề có thể kết hợp công việc của chúng hiệu quả hơn. Các quy trình cần phải dồn kết quả của họ để kết hợp chúng cần có thời gian. are best for IO tasks or tasks involving external systems because threads can combine their work more efficiently. Processes need to pickle their results to combine them which takes time.
  • Chủ đề không cung cấp lợi ích trong Python cho các nhiệm vụ chuyên sâu CPU vì Gil.provide no benefit in python for CPU intensive tasks because of the GIL.

*Đối với các hoạt động nhất định như DOT Product, Numpy hoạt động xung quanh Python, Gil và thực thi mã song song.

Ví dụ xử lý song song

Python sườn đồng thời. Thư viện hoàn toàn dễ chịu khi làm việc với. Chỉ cần vượt qua chức năng của bạn, một danh sách các mục để làm việc và số lượng công nhân. Trong một vài phần tiếp theo, tôi đi qua các thí nghiệm khác nhau mà tôi đã chạy để tìm hiểu thêm về thời điểm sử dụng chuỗi so với xử lý.

def multithreading(func, args, 
workers):
with ThreadPoolExecutor(workers) as ex:
res = ex.map(func, args)
return list(res)
def multiprocessing(func, args,
workers):
with ProcessPoolExecutor(work) as ex:
res = ex.map(func, args)
return list(res)

Cuộc gọi API

Tôi tìm thấy các chủ đề hoạt động tốt hơn cho các cuộc gọi API và quan sát tăng tốc quá trình xử lý và đa xử lý nối tiếp.

def download(url):
try:
resp = urlopen(url)
except Exception as e:
print ('ERROR: %s' % e)

2 chủ đề

4 chủ đề

2 quy trình

4 quy trình

Nhiệm vụ nặng nề của IO

Tôi đã vượt qua trong một loạt các chuỗi văn bản khổng lồ để xem hiệu suất viết khác nhau như thế nào. Chủ đề dường như giành chiến thắng ở đây, nhưng đa xử lý cũng cải thiện thời gian chạy.

def io_heavy(text):
f = open('output.txt', 'wt', encoding='utf-8')
f.write(text)
f.close()

Nối tiếp

%timeit -n 1 [io_heavy(TEXT,1) for i in range(N)]
>> 1 loop, best of 3: 1.37 s per loop

4 chủ đề

4 quy trình

Nhiệm vụ nặng nề của IO

Tôi đã vượt qua trong một loạt các chuỗi văn bản khổng lồ để xem hiệu suất viết khác nhau như thế nào. Chủ đề dường như giành chiến thắng ở đây, nhưng đa xử lý cũng cải thiện thời gian chạy.

def cpu_heavy(n):
count = 0
for i in range(n):
count += i

Nối tiếp 4.2 seconds
4 threads: 6.5 seconds
4 processes: 1.9 seconds

CPU chuyên sâu

Đa xử lý đã giành chiến thắng trong ngày ở đây như mong đợi. Các quá trình tránh Gil và thực thi mã đồng thời trên nhiều lõi.

def dot_product(i, base):
start = time.time() - base
res = np.dot(a,b)
stop = time.time() - base
return start,stop

SERIAL: 4.2 giây4 Chủ đề: 6,5 giây4 Quy trình: 1,9 giây 2.8 seconds
2 threads: 3.4 seconds
2 processes: 3.3 seconds

Sản phẩm chấm numpy

Đúng như dự đoán, tôi đã thấy không có lợi ích gì khi thêm các chủ đề hoặc quy trình vào mã này. Numpy thực hiện mã C bên ngoài phía sau hậu trường và do đó trốn tránh Gil.

SERIAL: 2,8 giây2 Chủ đề: 3,4 giây2 Quy trình: 3,3 giây

Làm thế nào để python xử lý?

Sự song song thực sự trong Python đạt được bằng cách tạo ra nhiều quy trình, mỗi quá trình có một thông dịch viên Python với Gil riêng. Python có ba mô -đun cho đồng thời: đa xử lý, luồng và asyncio. Khi các nhiệm vụ chuyên sâu CPU, chúng ta nên xem xét mô -đun đa xử lý.creating multiple processes, each having a Python interpreter with its own separate GIL. Python has three modules for concurrency: multiprocessing , threading , and asyncio . When the tasks are CPU intensive, we should consider the multiprocessing module.

Có bao nhiêu quy trình có thể sử dụng trong Python?

Số lượng quy trình công nhân tối đa có thể bị giới hạn bởi hệ điều hành của bạn. Ví dụ: trên Windows, bạn sẽ không thể tạo hơn 61 quy trình con trong chương trình Python của mình. Các hệ điều hành khác như MacOS và Linux có thể áp đặt giới hạn trên đối với số lượng các quy trình có thể được sinh ra hoặc nĩa.on windows, you will not be able to create more than 61 child processes in your Python program. Other operating systems like MacOS and Linux may impose an upper limit on the number of processes that may be spawned or forked.

Làm thế nào để python đa luồng hoạt động?

MultiThreading (đôi khi chỉ đơn giản là "luồng") là khi một chương trình tạo ra nhiều luồng với việc thực hiện chu kỳ giữa chúng, vì vậy một tác vụ chạy dài hơn không chặn tất cả các chủ đề khác.Điều này hoạt động tốt cho các nhiệm vụ có thể được chia thành các nhiệm vụ nhỏ hơn, sau đó có thể được trao cho một luồng được hoàn thành.when a program creates multiple threads with execution cycling among them, so one longer-running task doesn't block all the others. This works well for tasks that can be broken down into smaller subtasks, which can then each be given to a thread to be completed.

Làm thế nào để xếp hàng đa xử lý Python hoạt động?

Đa xử lý.Hàng đợi cung cấp hàng đợi FIFO đầu tiên, đầu tiên, có nghĩa là các mục được lấy từ hàng đợi theo thứ tự chúng được thêm vào.Các mục đầu tiên được thêm vào hàng đợi sẽ là các mục đầu tiên được truy xuất.Điều này trái ngược với các loại hàng đợi khác như hàng đợi trước, lần đầu tiên và ưu tiên.provides a first-in, first-out FIFO queue, which means that the items are retrieved from the queue in the order they were added. The first items added to the queue will be the first items retrieved. This is opposed to other queue types such as last-in, first-out and priority queues.