01/10/2018, 09:07
Lập trình với multiprocessing
Mọi người cùng chia sẻ kinh nghiệm của mình về multiprocessing đi ạ.
import time
def task(name):
# 1 second for 1 task
time.sleep(1)
print('finish task : ', name)
list_task = range(10)
from multiprocessing import Process
# 10 task > 10s
for t in list_task:
# task(t)
Process(target=task, args=(t,)).start()
Mình mở topic nên chọn phần dễ trước
- Không bao giờ edit biến Global, GLOBAL chỉ nên là hằng số. Vì ta không biết biến global sẽ thay đổi khi nào trong multiprocessing.
Xin kinh nghiệm của mọi người
Bài liên quan
Hi Luan.
Nhảm. (@_@!)
Thế bạn nghĩ sao thì chia sẻ, có sai thì chỉ chứ sao lại nói thế, đây là diễn đàn dạy nhay học chứ có phải diễn đàn chuyên nghiệp đâu, ai cũng có quyền hiểu sai, quan trọng là chia sẻ để biết sai mà sửa chứ.
Bạn muốn thể hiện điều gì ?
Hi Luan.
Cái gì cần là hằng số thì là hằng số cái gì không là hằng số thì không là hằng số.
Mình thích câu phát biểu của bạn, thế nhưng đây không phải là học cửu âm chân kinh trong phim Tàu.
Bạn có thực sự hiểu mình muốn nói gì không vậy ? sorry nếu mình giải thích kém hay hành văn không rõ ràng.
Mình nói đây là không nên EDIT các biến trên GLOBAL. Mọi người có thói quen gọi 1 biến trên GLOBAL rồi dùng chung cho 1 đống function, mỗi function edit 1 kiểu. Thế nhưng điều đó trong multiprocess sẽ dẫn tới những lỗi không mong muốn. Vì không biết process nào xong trước, không thể xác định cái biến của bạn bị edit thành cái dạng gì, cho nên khi khai báo GLOBAL chỉ nên là hằng số và không nên bị thay đổi bởi bất kì function nào.
Hi Luan.
Vấn đề biến toàn cục không liên qua gì đến đa tiến trình cả. Hạn chế dùng biến toàn cục là một thói quen tốt của lập trình viên trong mọi trường hợp không chỉ trong đa tiến trình.
P/S Hoặc ban bỏ phần đa tiến trình đi chỉ nói đên biến toàn cục và đóng gói dữ liệu hoặc là nói đến các vấn đề chính của đa tiến trình.
Ok, cái mình cần là những chia sẻ như thế này. Vậy lúc lập trình đa tiến trình, bạn có tâm đắc hay kinh nghiệm gì không ? Có cái gì cần tránh hoặc chú ý ?
Mình nói về biến toàn cục vì vấn đề mình gặp phải lúc lập trình liên quan tới đa tiến trình, mình không kiểm soát được nên gây ra rất nhiều lỗi, mà muốn kiểm soát thì rất rắc rối, bởi vậy mình mới gộp chung vào.
Lúc trước cũng có người nói về vụ biến toàn cục, thế nhưng lập trình bình thường thì mọi thứ êm xuôi, cho đến khi đụng vấn đề xử lý đa tiến trình này.
Hi Luan.
Mai bàn.
1 Vấn đê biến toàn cục êm khi bạn code nhỏ chí có 1 người code v.v.v… nói chung là bạn vẫn quản lý được từng dòng code.
2 Vấn đề đa luồng thì có một số cái.
2.1 Trạng thái của một tiến chình chưa được chạy, đang chạy, đã chạy, có lỗi thoát ra.
2.2 Vấn đề tương tác giữa các luồng chay luồng, dừng luồng, chờ luồng.
2.3 Vấn để truyền dữ liệu vào, lấy dữ liệu ra trao đổi dữ liệu khi đang chạy luồng.
2.4 Đồng bộ và bất đồng bộ.
P/S Mình chưa có nhiều luồng bao giờ nghe gian hồ họ đồn thế.
1 tuần rồi không có ai hưởng ứng hết, mình tự kỷ vậy. Mấy người biết thì không quan tâm, còn người quan tâm thì không biết. Hôm nay rảnh giới thiệu cho người chưa biết vậy.
Giới Thiệu
multiprocessing nói đơn giản là 1 module cho phép mình goi nhiều process con chạy song song. giúp tận dụng đc tài nguyên của máy để tăng tốc độ giải quyết vấn đề.
Ví dụ
Mình lấy ví dụ từ thớt này nhé Làm sao để lấy được các text trong và ngoài thẻ a đây hả các bác
Mô tả: Lấy tất cả nội dung của glosarry trên trang đó lưu lại dưới dạng Json.
vậy để giải quyết vấn đề mình cần mấy module sau
Mình viết 1 function, lấy nội dung cho từng chữ cái :
Cách làm bình thường:
Trên web http://www.imdb.com/glossary/ mình thấy các chữ cái từ A tới Z, vậy mình sẽ phải gọi
list_glossay
cho từng chữ cái.Và mình ngồi chờ nó load từng trang, xong hết với mạng nhà mình tầm 20s. Tuy đợi chờ là hạnh phúc nhưng mình trả 1 đống tiền xương máu mua con i5 với cúng tiền hàng tháng cho cái cáp quang thỉnh thoảng bị cá mập cắn thì không lý do gì mình không tận thu. Vậy nên mình xài multiprocessing.
Mình thấy cái function load dữ liệu từng trang nó độc lập với nhau, vậy sao không chạy 26 cái cùng 1 lúc thay vì ngồi đợi từng cái tiếp từng cái.
vậy nên mình viết lại :
Xong rồi, xem kết quả thôi : lần này mình mất chưa đến 3s. nhanh hơn 10 lần
To be continue
Chắc chắn có bác sẽ thắc mắc là sao mình không để vào một file ? điều này sẽ hơi rắc rối vì là vấn đề chia sẻ dữ liệu của nhiều process chạy song song. với multiprocessing sẽ rất rắc rối và khó hiểu, sẽ mất nhiều thời gian cho người mới. Nếu thớt đc mấy bác quan tâm, mình sẽ giới thiệu tiếp. Lần sau sẽ là goless, một module theo ngôn ngữ GO, chức năng tương tự multiprocessing nhưng có cách viết dễ hiểu hơn, tiện lợi hơn, sẽ giải quyết vấn đề này.
Còn bác nào nghĩ tạo biến GLOBAL thì lạy hồn, mình nói rồi, không chạy đâu. Nếu bác nào nghĩ đến Lock() thì có khả năng đấy, nhưng đó là 1 vấn đề khác nũa của multiprocessing, có nhiều điều để bàn lắm, trong đk bài viết này mình sẽ không nói đến.
Hi NG.
Bài viết rất hữu ích. Bạn có link trên github không để minh bookmap lại khi nào cần xem lại cho tiện.
Còn về phần chia sẻ dữ liệu thì thường làm theo kiểu oop nó có dữ liệu riêng và đóng gói khá ổn. Nếu không có thể tạo struct để lưu trữ cho mỗi luồng. Cũng là một cách triển khai oop.
Hóng phần tiếp theo của bác . Bác làm cái blog cho ae dễ theo dõi .
Ok, khi nào rảnh mình sẽ up code lên github.