Mô-đun
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']6 cho phép lập trình viên tận dụng tối đa nhiều bộ xử lý trên một máy nhất định. API được sử dụng tương tự như mô-đun
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']7 cổ điển. Nó cung cấp cả đồng thời cục bộ và từ xa
Mô-đun đa xử lý tránh các hạn chế của Khóa thông dịch viên toàn cầu [GIL] bằng cách sử dụng các quy trình con thay vì các luồng. Mã đa xử lý không thực thi theo thứ tự như mã nối tiếp. Không có gì đảm bảo rằng quy trình đầu tiên được tạo sẽ là quy trình đầu tiên hoàn thành
Mãng xà
Khóa trình thông dịch toàn cầu [GIL] là một cơ chế được sử dụng trong trình thông dịch Python để đồng bộ hóa việc thực thi các luồng sao cho chỉ một luồng gốc có thể thực thi tại một thời điểm, ngay cả khi chạy trên bộ xử lý đa lõi
Các tiện ích mở rộng C, chẳng hạn như numpy, có thể giải phóng GIL theo cách thủ công để tăng tốc độ tính toán. Ngoài ra, GIL được phát hành trước khi có khả năng chặn các hoạt động I/O
Lưu ý rằng cả Jython và IronPython đều không có GIL
Đồng thời và song song
Đồng thời có nghĩa là hai hoặc nhiều phép tính xảy ra trong cùng một khung thời gian. Tính song song có nghĩa là hai hoặc nhiều phép tính xảy ra cùng một lúc. Do đó, song song là một trường hợp cụ thể của đồng thời. Nó yêu cầu nhiều đơn vị CPU hoặc lõi
Tính song song thực sự trong Python đạt được bằng cách tạo nhiều quy trình, mỗi quy trình có một trình thông dịch Python với GIL riêng của nó
Python có ba mô-đun để xử lý đồng thời.
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']6,
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']7 và
$ ./joining.py starting main starting fun finishing fun finishing main0. Khi các tác vụ sử dụng nhiều CPU, chúng ta nên xem xét mô-đun
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']6. Khi các tác vụ bị ràng buộc I/O và yêu cầu nhiều kết nối, mô-đun
$ ./joining.py starting main starting fun finishing fun finishing main0 được khuyến nghị. Đối với các loại nhiệm vụ khác và khi các thư viện không thể hợp tác với
$ ./joining.py starting main starting fun finishing fun finishing main0, mô-đun
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']7 có thể được xem xét
Xấu hổ song song
Thuật ngữ song song đáng xấu hổ được sử dụng để mô tả một vấn đề hoặc khối lượng công việc có thể dễ dàng chạy song song. Điều quan trọng là phải nhận ra rằng không phải tất cả các khối lượng công việc đều có thể được chia thành các nhiệm vụ con và chạy song song. Chẳng hạn, những người cần nhiều giao tiếp giữa các nhiệm vụ con
Các ví dụ về tính toán song song hoàn hảo bao gồm
- phân tích Monte Carlo
- hội nhập số
- kết xuất đồ họa máy tính
- tìm kiếm vũ phu trong mật mã
- thuật toán di truyền
Một tình huống khác mà tính toán song song có thể được áp dụng là khi chúng ta chạy một số tính toán khác nhau, tức là chúng ta không chia bài toán thành các nhiệm vụ con. Chẳng hạn, chúng ta có thể chạy song song các phép tính của π bằng các thuật toán khác nhau
Quy trình so với luồng
Cả quy trình và luồng đều là các chuỗi thực thi độc lập. Bảng sau đây tóm tắt sự khác biệt giữa một quy trình và một luồng
Quy trình Các quy trình xử lý chạy trong bộ nhớ riêng biệt [cách ly quy trình] các luồng chia sẻ bộ nhớ sử dụng nhiều bộ nhớ hơn sử dụng ít bộ nhớ hơntrẻ em có thể trở thành thây makhông có thây ma nào có thể. Thêm chi phí không tốn kém hơn để tạo và hủy tạo và hủy nhanh hơn. Tạo và hủy dễ viết mã và gỡ lỗi hơn có thể trở nên khó viết mã và gỡ lỗi hơnQuá trình
Đối tượng
$ ./joining.py starting main starting fun finishing fun finishing main5 đại diện cho một hoạt động được chạy trong một quy trình riêng biệt. Lớp
$ ./joining.py starting main starting fun finishing fun finishing main6 tương đương với tất cả các phương thức của
$ ./joining.py starting main starting fun finishing fun finishing main7. Hàm tạo
$ ./joining.py starting main starting fun finishing fun finishing main5 phải luôn được gọi với các đối số từ khóa
Đối số
$ ./joining.py starting main starting fun finishing fun finishing main9 của hàm tạo là đối tượng có thể gọi được gọi bằng phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']40.
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']41 là tên quy trình. Phương pháp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']42 bắt đầu hoạt động của quy trình. Phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 chặn cho đến khi quá trình có phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 được gọi là kết thúc. Nếu tùy chọn
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']45 được cung cấp, nó sẽ chặn hầu hết các giây hết thời gian chờ. Phương thức ________ 146 trả về một giá trị boolean cho biết tiến trình có còn hoạt động hay không. Phương pháp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']47 kết thúc quá trình
Người bảo vệ __main__
Hướng dẫn kiểu đa xử lý Python khuyến nghị đặt mã đa xử lý bên trong thành ngữ
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']48. Điều này là do cách các quy trình được tạo trên Windows. Người bảo vệ là để ngăn chặn vòng lặp vô tận của các thế hệ quy trình
Ví dụ quy trình đơn giản
Sau đây là một chương trình đơn giản sử dụng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']6
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']4
Chúng tôi tạo một quy trình mới và chuyển một giá trị cho nó
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']5
Hàm in tham số đã truyền
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']6
Một quy trình mới được tạo ra. Tùy chọn
$ ./joining.py starting main starting fun finishing fun finishing main9 cung cấp khả năng gọi được chạy trong quy trình mới.
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']81 cung cấp dữ liệu được thông qua. Mã đa xử lý được đặt bên trong bộ phận bảo vệ chính. Quá trình được bắt đầu với phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']42
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']0
Mã được đặt bên trong thành ngữ
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']48
Tham gia đa xử lý Python
Phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 chặn việc thực thi quy trình chính cho đến khi quy trình có phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 được gọi là kết thúc. Không có phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43, quy trình chính sẽ không đợi cho đến khi quy trình kết thúc
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']
Ví dụ gọi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 trên quy trình mới được tạo
$ ./joining.py starting main starting fun finishing fun finishing main
Thông báo chính kết thúc được in sau khi quá trình con kết thúc
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']4
Khi chúng tôi nhận xét phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43, quy trình chính kết thúc trước quy trình con
Điều quan trọng là gọi các phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 sau các phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']42
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']8
Nếu chúng ta gọi các phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43 không chính xác, thì trên thực tế, chúng ta sẽ chạy các quy trình một cách tuần tự. [Cách không chính xác được nhận xét. ]
Đa xử lý Python is_alive
Phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']46 xác định xem tiến trình có đang chạy hay không
$ ./joining.py starting main starting fun finishing fun finishing main5
Khi chúng ta đợi tiến trình con kết thúc với phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43, tiến trình đã chết khi chúng ta kiểm tra nó. Nếu chúng tôi nhận xét
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']43, quá trình này vẫn còn hiệu lực
Id tiến trình đa xử lý của Python
$ ./joining.py starting main starting fun finishing fun finishing main55 trả về Id quy trình hiện tại, trong khi
$ ./joining.py starting main starting fun finishing fun finishing main56 trả về Id quy trình cha
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']0
Ví dụ chạy hai tiến trình con. Nó in Id của họ và Id của cha mẹ họ
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']50
Id cha giống nhau, Id tiến trình khác nhau đối với mỗi tiến trình con
quy trình đặt tên
Với thuộc tính
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']41 của
$ ./joining.py starting main starting fun finishing fun finishing main5, chúng ta có thể đặt tên cụ thể cho worker. Mặt khác, mô-đun tạo tên riêng của nó
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']51
Trong ví dụ này, chúng tôi tạo ba quy trình;
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']52
Quy trình phân lớp
Khi chúng tôi phân lớp
$ ./joining.py starting main starting fun finishing fun finishing main5, chúng tôi ghi đè phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']40
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']53
Chúng tôi tạo một lớp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']01 kế thừa từ lớp
$ ./joining.py starting main starting fun finishing fun finishing main5. Trong phương pháp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']40, chúng tôi viết mã của công nhân
Nhóm đa xử lý Python
Việc quản lý các worker process có thể được đơn giản hóa với đối tượng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']04. Nó kiểm soát một nhóm các quy trình công nhân mà các công việc có thể được gửi tới. Phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']05 của nhóm chia nhỏ khả năng lặp đã cho thành một số phần mà nó gửi tới nhóm quy trình dưới dạng các tác vụ riêng biệt.
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']05 của nhóm tương đương song song với phương pháp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']05 tích hợp.
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']05 chặn thực thi chính cho đến khi tất cả các tính toán kết thúc
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']04 có thể lấy số lượng quy trình làm tham số. Đó là một giá trị mà chúng ta có thể thử nghiệm. Nếu chúng tôi không cung cấp bất kỳ giá trị nào, thì số được trả về bởi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']500 được sử dụng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']54
Trong ví dụ này, chúng tôi tạo một nhóm các quy trình và áp dụng các giá trị trên hàm
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']501. Số lượng lõi được xác định bằng hàm
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']502
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']55
Trên máy tính có bốn lõi, chỉ mất hơn 2 giây để hoàn thành bốn phép tính, mỗi phép tính kéo dài hai giây
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']56
Khi chúng tôi thêm giá trị bổ sung để tính toán, thời gian tăng lên hơn bốn giây
Nhiều đối số
Để truyền nhiều đối số cho hàm worker, chúng ta có thể sử dụng phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']503. Các phần tử của iterable dự kiến là iterables được giải nén dưới dạng đối số
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']57
Trong ví dụ này, chúng ta chuyển hai giá trị cho hàm
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']504. giá trị và số mũ
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']58
Nhiều chức năng
Ví dụ sau đây cho thấy cách chạy nhiều chức năng trong một nhóm
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']59
Chúng tôi có ba chức năng, được chạy độc lập trong một nhóm. Chúng tôi sử dụng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']505 để chuẩn bị các hàm và tham số của chúng trước khi chúng được thực thi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']60
Python đa xử lý tính toán π
π là tỷ số giữa chu vi của bất kỳ hình tròn nào với đường kính của hình tròn đó. Số π là một số vô tỷ có dạng thập phân không kết thúc và không lặp lại. Nó xấp xỉ bằng 3. 14159. Có một số công thức để tính π
Việc tính toán các xấp xỉ của π có thể mất nhiều thời gian, vì vậy chúng ta có thể tận dụng các phép tính song song. Chúng tôi sử dụng công thức Bailey–Borwein–Plouffe để tính π
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']61
Đầu tiên, chúng tôi tính toán ba xấp xỉ tuần tự. Độ chính xác là số chữ số của π được tính toán
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']62
Trên máy của chúng tôi, phải mất 0. 57381 giây để tính ba giá trị gần đúng
Trong ví dụ sau, chúng tôi sử dụng một nhóm quy trình để tính toán ba giá trị gần đúng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']63
Chúng tôi chạy các tính toán trong một nhóm gồm ba quy trình và chúng tôi đạt được một số hiệu quả tăng nhẹ
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']64
Khi chúng tôi chạy các phép tính song song, phải mất 0. 38216479 giây
Bộ nhớ riêng biệt trong một quá trình
Trong đa xử lý, mỗi worker có bộ nhớ riêng. Bộ nhớ không được chia sẻ như trong luồng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']65
Chúng tôi tạo một công nhân mà chúng tôi chuyển danh sách
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']506 toàn cầu. Chúng tôi thêm các giá trị bổ sung vào danh sách trong worker nhưng danh sách ban đầu trong quy trình chính không được sửa đổi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']66
Như chúng ta có thể thấy từ đầu ra, hai danh sách là riêng biệt
Chia sẻ trạng thái giữa các tiến trình
Dữ liệu có thể được lưu trữ trong bộ nhớ dùng chung bằng cách sử dụng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']507 hoặc
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']508
Ghi chú. Tốt nhất là tránh chia sẻ dữ liệu giữa các quy trình. Truyền tin nhắn được ưu tiên
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']67
Ví dụ tạo một đối tượng truy cập được chia sẻ giữa các quy trình. Mỗi quy trình làm tăng bộ đếm
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']68
Mỗi quá trình phải có được một khóa cho chính nó
Tin nhắn đi với hàng đợi
Truyền thông điệp là cách giao tiếp ưa thích giữa các tiến trình. Truyền tin nhắn tránh phải sử dụng các nguyên tắc đồng bộ hóa như khóa, khó sử dụng và dễ xảy ra lỗi trong các tình huống phức tạp
Để truyền thông điệp, chúng ta có thể sử dụng đường ống để kết nối giữa hai quy trình. Hàng đợi cho phép nhiều nhà sản xuất và người tiêu dùng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']69
Trong ví dụ này, chúng tôi tạo bốn quy trình. Mỗi quá trình tạo ra một giá trị ngẫu nhiên và đặt nó vào hàng đợi. Sau khi tất cả các quy trình kết thúc, chúng tôi nhận được tất cả các giá trị từ hàng đợi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']00
Hàng đợi được truyền dưới dạng đối số cho quy trình
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']01
Phương thức
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']509 loại bỏ và trả về mục từ hàng đợi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']02
Ví dụ tạo danh sách bốn giá trị ngẫu nhiên
Trong ví dụ sau, chúng tôi đặt các từ trong hàng đợi. Các quy trình được tạo đọc các từ từ hàng đợi
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']03
Bốn quy trình được tạo ra;
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']04
thứ tự xếp hàng
Trong đa xử lý, không có gì đảm bảo rằng các quy trình kết thúc theo một thứ tự nhất định
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']05
Chúng tôi có các quy trình tính bình phương của một giá trị. Dữ liệu đầu vào theo thứ tự nhất định và chúng ta cần duy trì thứ tự này. Để giải quyết vấn đề này, chúng tôi giữ một chỉ mục bổ sung cho mỗi giá trị đầu vào
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']06
Để minh họa sự thay đổi, chúng tôi ngẫu nhiên làm chậm quá trình tính toán bằng phương pháp
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']510. Chúng tôi đặt một chỉ mục vào hàng đợi với hình vuông được tính toán
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']07
Chúng tôi nhận được kết quả. Tại thời điểm này, các bộ dữ liệu theo thứ tự ngẫu nhiên
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']08
Chúng tôi sắp xếp dữ liệu kết quả theo giá trị chỉ mục của chúng
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']09
Chúng tôi nhận được các giá trị bình phương tương ứng với dữ liệu ban đầu
Tính π bằng phương pháp Monte Carlo
Các phương pháp Monte Carlo là một lớp rộng các thuật toán tính toán dựa trên việc lấy mẫu ngẫu nhiên lặp đi lặp lại để thu được kết quả số. Khái niệm cơ bản là sử dụng tính ngẫu nhiên để giải quyết các vấn đề có thể mang tính quyết định về nguyên tắc
Công thức sau đây được sử dụng để tính xấp xỉ của π
π4≈MNM là số điểm được tạo trong hình vuông và N là tổng số điểm
Mặc dù phương pháp tính số π này rất thú vị và hoàn hảo cho các ví dụ ở trường học, nhưng nó không chính xác lắm. Có nhiều thuật toán tốt hơn để có được π
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']0
Trong ví dụ này, chúng tôi tính giá trị gần đúng của giá trị π bằng cách sử dụng một trăm triệu điểm ngẫu nhiên được tạo
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']1
mất 44. 78 giây để tính xấp xỉ của π
Bây giờ chúng ta chia toàn bộ nhiệm vụ tính toán π thành các nhiệm vụ con
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']2
Trong ví dụ này, chúng tôi tìm ra số lượng lõi và chia việc lấy mẫu ngẫu nhiên thành các nhiệm vụ con. Mỗi tác vụ sẽ tính toán các giá trị ngẫu nhiên một cách độc lập
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']3
Thay vì tính 100_000_000 trong một lần, mỗi nhiệm vụ con sẽ tính một phần của nó
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']4
Các tính toán từng phần được chuyển đến biến
#!/usr/bin/python from multiprocessing import Process import time def fun[]: print['starting fun'] time.sleep[2] print['finishing fun'] def main[]: p = Process[target=fun] p.start[] p.join[] if __name__ == '__main__': print['starting main'] main[] print['finishing main']511 và tổng sau đó được sử dụng trong công thức cuối cùng