- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Với sự phát triển của lập trình đa lõi, đồng thời trong Python ngày càng phổ biến và phát triển nhanh chóng.
Một mặt, Python cung cấp nhiều công cụ lập trình đồng thời.
Ví dụ: đa luồng truyền thống có thể dễ dàng tạo và quản lý các luồng thông qua mô-đun luồng, mô-đun này có thể được sử dụng cho các tác vụ đòi hỏi nhiều I/O;
Đa tiến trình, sử dụng mô-đun đa xử lý để tận dụng tối đa CPU đa lõi, phù hợp với các tác vụ đòi hỏi nhiều CPU.
Mặt khác, với sự gia tăng của lập trình không đồng bộ. Thư viện asyncio cũng cho phép các nhà phát triển viết mã không đồng bộ hiệu quả và cải thiện hiệu suất chương trình, đặc biệt khi xử lý một số lượng lớn các kịch bản hoạt động I/O đồng thời.
Tuy nhiên, Khóa phiên dịch toàn cầu (GIL) trong Python đã mang đến những thách thức đáng kể cho việc lập trình đồng thời. Hiện tại, cộng đồng đang tích cực khám phá các phương pháp và chiến lược tối ưu hóa để vượt qua GIL nhằm thúc đẩy quá trình phát triển liên tục của lập trình đồng thời Python.
Bài viết này dự định giới thiệu lần lượt cách sử dụng các phương thức đa luồng, đa tiến trình hoặc không đồng bộ để viết chương trình trong Python.
Mô-đun đa luồng trong Python là threading, được thêm vào thư viện chuẩn ngay từ Python 1.5.
Phân luồng đã được phát triển, đặc biệt là sau khi vào Python3.x.
Từ Python3.3 đến Python3.13, hầu hết mọi bản nâng cấp Python đều đi kèm với các thay đổi về luồng.
Do đó, khi sử dụng nó, hãy đảm bảo sử dụng giao diện luồng chính xác theo phiên bản Python của bạn.
Tính năng đa luồng của Python được sử dụng rộng rãi trong các tình huống tác vụ đòi hỏi nhiều I/O, chẳng hạn như yêu cầu mạng, đọc và ghi tệp, v.v., cho phép chương trình chuyển sang các luồng khác trong khi chờ thao tác I/O, từ đó cải thiện hiệu quả tổng thể.
Khi các kịch bản ứng dụng mở rộng, những hạn chế của đa luồng dần dần được nêu bật.
Điều quan trọng nhất là Khóa phiên dịch toàn cầu (GIL), đây là một tính năng của trình thông dịch Python. Mỗi lần chỉ có một luồng có thể thực thi mã byte Python.
Điều này dẫn đến việc đa luồng không thể tận dụng tối đa ưu điểm của CPU đa lõi trong các tác vụ ngốn CPU và sự cải thiện hiệu năng không rõ ràng, thậm chí có thể giảm đi.
Tuy nhiên, bất chấp những hạn chế của nó, đa luồng vẫn đóng một vai trò quan trọng trong hệ sinh thái Python.
Các nhà phát triển tiếp tục khám phá các phương pháp tối ưu hóa, chẳng hạn như sử dụng luồng kết hợp với các mô-đun tương tranh khác như đa xử lý, để tối đa hóa điểm mạnh và tránh điểm yếu. Đồng thời, phiên bản Python mới cũng đang cố gắng cải thiện cơ chế GIL để cung cấp nhiều khả năng phát triển đa luồng hơn.
Trong quá trình phát triển thực tế, có ba cách chính để sử dụng đa luồng:
Cách đầu tiên là tạo thread trực tiếp bằng lớp threading.Thread.
Đây là cách cơ bản nhất, trực tiếp khởi tạo lớp threading.Thread và truyền vào hàm đích và các tham số.
import threading def worker(): print('Thread is doing') # Tạo thread t = threading.Thread(target=worker) # Bắt đầu thread t.start() # Đợi thread hoàn thành việc thực thi t.join()
Cách thứ hai là tạo một lớp luồng bằng cách kế thừa lớp threading.Thread và ghi đè phương thức run để xác định các tác vụ được thực hiện bởi luồng.
nhập lớp luồng MyThread(threading.Thread): def run(self): print(f'{self.name} luồng đang thực thi') #Tạo phiên bản luồng my_thread = MyThread() #Start thread my_thread.start() #Wait for thread Đã hoàn thành việc thực thi my_thread.join()
Cách cuối cùng là sử dụng threading.ThreadPool để triển khai nhóm luồng. Trong Python 3, nên sử dụng ThreadPoolExecutor trong mô-đun concurrent.futures để triển khai chức năng nhóm luồng.
threading.ThreadPool đã được đánh dấu là lỗi thời và không được khuyến khích sử dụng trong các dự án mới.
Ưu điểm của nhóm luồng là nó có thể quản lý một nhóm luồng, tái sử dụng tài nguyên luồng và giảm chi phí tạo và hủy luồng.
import concurrent.futures def task(num): print(f"Execute task{num}") return num * 2 # Tạo một nhóm luồng, số lượng luồng tối đa là 3 với concurrent.futures.ThreadPoolExecutor(max_workers=3) là người thực thi: # Gửi tác vụ Future_to_num = {executor.submit(task, num): num for num in range(5)} cho tương lai trong concurrent.futures.as_completed(future_to_num): num = Future_to_num[future] try: result = Future.result() ngoại trừ Ngoại lệ là e: print(f"Task {num} không thực thi được: {e}") else: print( f "Nhiệm vụ {num} kết quả: {result}")
Kết quả thực hiện:
$ python.exe .\thread.py Thực thi nhiệm vụ 0 Thực thi nhiệm vụ 1 Thực thi nhiệm vụ 2 Thực thi nhiệm vụ 3 Kết quả nhiệm vụ 1: 2 Thực thi nhiệm vụ 4 Kết quả nhiệm vụ 2: 4 Kết quả nhiệm vụ 0: 0 Kết quả nhiệm vụ 3: 6 Kết quả nhiệm vụ 4: 8
Mô-đun đa xử lý đa luồng đã được giới thiệu trong Python 2.6 và tiếp tục phát triển trong Python 3.x.
Trong quá trình phát triển, đa xử lý liên tục được cải tiến. Nó cung cấp một giao diện đơn giản và mạnh mẽ, cho phép các nhà phát triển dễ dàng tạo và quản lý nhiều quy trình, tận dụng tối đa lợi thế của CPU đa lõi và cải thiện đáng kể hiệu quả xử lý các tác vụ sử dụng nhiều CPU.
Nó hỗ trợ nhiều phương thức giao tiếp giữa các quá trình, chẳng hạn như hàng đợi, đường ống, v.v., để tạo điều kiện chia sẻ và đồng bộ hóa dữ liệu giữa các quy trình.
Đa xử lý phù hợp với tính toán sử dụng nhiều CPU, chẳng hạn như tính toán khoa học, phân tích dữ liệu, xử lý hình ảnh và các tác vụ khác đòi hỏi lượng lớn tài nguyên máy tính.
Đa xử lý cũng có thể được sử dụng khi có nhiều tác vụ độc lập cần được thực thi đồng thời, chẳng hạn như xử lý tệp hàng loạt, xử lý hàng đợi tác vụ, v.v. Một quy trình có thể được chỉ định cho từng nhiệm vụ để nâng cao hiệu quả thực hiện nhiệm vụ.
Ngoài ra, trong một số ứng dụng máy chủ, nhiều quy trình cũng có thể được sử dụng để cho phép quy trình chính xử lý các yêu cầu trong khi các quy trình khác chịu trách nhiệm về các tác vụ nền, chẳng hạn như cập nhật bộ đệm dữ liệu, ghi nhật ký, v.v., từ đó tránh chặn luồng chính và cải thiện tốc độ phản hồi của ứng dụng.
Tuy nhiên, đa xử lý cũng có một số hạn chế.
Vì mỗi tiến trình có một không gian bộ nhớ độc lập nên việc chia sẻ và liên lạc dữ liệu giữa các tiến trình tương đối phức tạp và yêu cầu các cơ chế và hoạt động đồng bộ hóa bổ sung, điều này có thể gây giảm hiệu suất.
Hơn nữa, việc tạo và hủy các tiến trình rất tốn kém và việc tạo và hủy các tiến trình thường xuyên sẽ ảnh hưởng đến hiệu suất tổng thể của chương trình.
Ngoài ra, các tình huống sử dụng của nó tương đối hạn chế và không phù hợp với các tác vụ đồng thời đơn giản. So với đa luồng, ưu điểm của nó trong các tác vụ đòi hỏi nhiều I/O là không rõ ràng, vì đa luồng có thể chuyển sang thực hiện các tác vụ khác trong khi chờ đợi. cho I/O. Nhiều quy trình sẽ tiêu tốn nhiều tài nguyên hơn.
Ở đây chúng tôi cũng giới thiệu ba cách phổ biến để sử dụng đa xử lý:
Cách đầu tiên là sử dụng trực tiếp lớp Process, bằng cách khởi tạo lớp multiprocessing.Process và truyền vào hàm đích và các tham số để tạo một quy trình.
import multiprocessing def worker(): print('Process is doing') if __name__ == '__main__': # Tạo tiến trình p = multiprocessing.Process(target=worker) # Bắt đầu tiến trình p.start() # Đợi quá trình hoàn tất p .join()
Cách thứ hai là xác định các tác vụ được thực hiện bởi tiến trình bằng cách kế thừa lớp multiprocessing.Process và ghi đè phương thức run.
nhập lớp đa xử lý MyProcess(multiprocessing.Process): def run(self): print(f'{self.name} tiến trình đang thực thi') if __name__ == '__main__': # Tạo một phiên bản tiến trình my_process = MyProcess() # Bắt đầu quy trình my_process.start() # Đợi quá trình hoàn tất my_process.join()
Cách cuối cùng là tạo một nhóm quy trình thông qua lớp multiprocessing.Pool, tự động gán nhiệm vụ cho các quy trình và cải thiện việc sử dụng tài nguyên.
import multiprocessing def task(num): return num * 2 if __name__ == '__main__': # Tạo một nhóm quy trình, số lượng quy trình tối đa là 3 với multiprocessing.Pool(processes=3) làm nhóm: # Sử dụng phương thức bản đồ để thực thi kết quả nhiệm vụ song song = pool.map(task, range(5)) print(results)
Ba phương pháp sử dụng này trông giống như phân luồng trong phần trước, nhưng quá trình xử lý cơ bản của chúng hoàn toàn khác nhau.
Đa xử lý tạo ra một quy trình riêng biệt để mỗi tác vụ thực thi; trong khi tất cả các tác vụ trong luồng đều được thực thi trong cùng một quy trình.
Lịch sử của mô-đun không đồng bộ asyncio muộn hơn nhiều so với hai mô-đun trên. Nó được giới thiệu lần đầu tiên trong Python 3.4.
Trong Python 3.5, các từ khóa async và wait đã được giới thiệu, giúp việc viết mã không đồng bộ ngắn gọn hơn và dễ đọc hơn, cải thiện đáng kể trải nghiệm lập trình không đồng bộ và thúc đẩy ứng dụng rộng rãi của asyncio.
asyncio phù hợp với các tình huống yêu cầu xử lý đồng thời cao sau:
Trình thu thập dữ liệu web: Khi thu thập dữ liệu nhiều trang web, asyncio có thể tiếp tục gửi các yêu cầu khác trong khi chờ phản hồi, cải thiện đáng kể hiệu quả thu thập dữ liệu và rút ngắn thời gian thu thập lượng lớn dữ liệu.
Phát triển máy chủ mạng: xử lý các kết nối máy khách có tính đồng thời cao, chẳng hạn như xây dựng máy chủ trò chuyện, dịch vụ đẩy dữ liệu thời gian thực, v.v. Nó có thể xử lý từng yêu cầu của khách hàng một cách không đồng bộ để tránh bị chặn và đảm bảo rằng máy chủ chạy hiệu quả.
Các tác vụ chuyên sâu về I/O: chẳng hạn như đọc và ghi tệp, vận hành cơ sở dữ liệu, v.v. asyncio có thể thực hiện các tác vụ khác trong khi chờ các thao tác I/O hoàn tất, giảm thời gian chờ tổng thể và cải thiện hiệu suất chương trình.
Tất nhiên, asyncio có những ưu điểm rõ ràng nhưng cũng có một số hạn chế.
Một mặt, vì dựa trên một luồng duy nhất nên nó có hiệu năng kém khi xử lý các tác vụ ngốn CPU và không thể tận dụng hết lợi thế của CPU đa lõi.
Mặt khác, mô hình lập trình không đồng bộ tương đối phức tạp, việc gỡ lỗi và bảo trì mã rất khó khăn. Các nhà phát triển cần có hiểu biết sâu sắc về các khái niệm không đồng bộ, nếu không sẽ dễ xảy ra lỗi logic.
Ngoài ra, asyncio có thể gặp vấn đề về khả năng tương thích với một số thư viện đồng bộ hóa truyền thống và bạn có thể gặp khó khăn khi tích hợp mã hiện có.
asyncio là một mô-đun tương đối mới. Công dụng chính của nó là:
độ phân giải không đồng bộ
Khai báo từ khóa, được sử dụng bên trong hàmchờ đợi
Từ khóa tạm dừng quá trình thực thi coroutine và chờ các hoạt động không đồng bộ khác hoàn tất.import asyncio async def coroutine(): print('Bắt đầu thực thi hàm coroutine') đang chờ asyncio.sleep(1) print('Việc thực thi hàm coroutine kết thúc') if __name__ == '__main__': asyncio.run(coroutine() )
asyncio.run() được dùng để chạy coroutine cấp cao nhất.
asyncio.gather()
Một hàm có thể chạy nhiều coroutine cùng một lúc.import asyncio async def coroutine1(): wait asyncio.sleep(1) print('Coroutine 1 đã được thực thi') async def coroutine2(): wait asyncio.sleep(2) print('Coroutine 2 đã được thực thi') if __name__ == "__main__": thử: loop = asyncio.get_running_loop() ngoại trừ RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) thử: loop.run_until_complete(asyncio.gather(coroutine1(), coroutine2())) cuối cùng: loop.close()
không đồng bộ cho
Lặp lại trên một đối tượng có thể lặp không đồng bộ.nhập asyncio async def async_generator(): for i in range(3): chờ asyncio.sleep(1) mang lại i async def main(): async for num in async_generator(): print(num) if __name__ == "__main__" : asyncio.run(main())
Phương pháp này phù hợp để xử lý các chuỗi dữ liệu được tạo không đồng bộ.
Tổng thể, .
Đa luồng là việc tạo ra nhiều luồng trong một quy trình để chia sẻ tài nguyên. Chi phí chuyển đổi luồng thấp và phù hợp với các tác vụ đòi hỏi nhiều I/O, chẳng hạn như yêu cầu mạng và đọc và ghi tệp.
Nó rất đơn giản để lập trình và có thể cải thiện khả năng phản hồi của chương trình, nhưng do khóa trình thông dịch toàn cầu nên nó không thể tận dụng được tính năng đa lõi trong các tác vụ sử dụng nhiều CPU và cũng có các vấn đề về an toàn luồng.
Mỗi tiến trình trong đa tiến trình có bộ nhớ và tài nguyên độc lập, phù hợp với các tác vụ sử dụng nhiều CPU. Nó có thể tận dụng tối đa CPU đa lõi và có độ ổn định cao.
Tuy nhiên, việc tạo và hủy quá trình rất tốn kém, đồng thời việc liên lạc và chia sẻ dữ liệu giữa các quá trình rất phức tạp.
Lập trình không đồng bộ dựa trên các vòng lặp sự kiện và coroutine, đạt được khả năng thực thi không đồng bộ trong một luồng duy nhất.
Nó có hiệu suất xử lý đồng thời cao, mã ngắn gọn và phù hợp với số lượng lớn các tác vụ đòi hỏi nhiều I/O. Nhưng nó không phù hợp với các tác vụ sử dụng nhiều CPU, mô hình lập trình phức tạp, việc gỡ lỗi và bảo trì rất khó khăn.
Nói một cách đơn giản, trong quá trình phát triển, hãy sử dụng ít đa luồng hơn cho các tác vụ cần nhiều I/O và nhiều tác vụ không đồng bộ hơn cho các tác vụ sử dụng nhiều CPU và kết hợp các tác vụ hỗn hợp theo yêu cầu;
Cuối cùng, bài viết này về tóm tắt đồng thời Python: lập trình đa luồng, đa quy trình và không đồng bộ kết thúc tại đây. Nếu bạn muốn biết thêm về tóm tắt đồng thời Python: lập trình đa luồng, đa quy trình và không đồng bộ, vui lòng tìm kiếm bài viết CFSDN. Hoặc tiếp tục duyệt các bài viết liên quan, tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi sử dụng Bootstrap với css command và java. người dùng giao diện mã hóa. tôi không thể sử dụng
Mã như sau: #include void main() { char line[90] while(scanf("%79[^\
Tôi muốn nhận tất cả các dòng cặp trong một mảng ma trận bằng javascript. = [ [1,2,3], [4,5,6], [7,8,9], ] đầu ra =
Có thể vẽ đường thẳng, hình tròn và các dạng hình khác bằng pdfmake không? pdfmake bằng jsPDF. Câu trả lời hay nhất Có, có thể là pdfm.
Tôi có một svg tiện ích thu nhỏ có mục tiêu hiển thị danh sách các góc (xem hình). một màu sắc rõ ràng và không có phần tô màu. không giải quyết được vấn đề này,
Tôi đang viết một bộ chuyển đổi ánh sáng rất cơ bản cho cảnh 3D với các vật thể hình tam giác, mọi thứ đều hoạt động tốt nhất là khi tôi quyết định thử chuyển đổi từ một điểm khác với bối cảnh gốc (0/0/0).
(22 câu trả lời lời?
Làm cách nào tôi có thể vẽ một đường ngang bằng cách sử dụng khoảng 50 dấu hoa thị* và sử dụng vòng lặp cho? public void drawAstline() { f
Đây là người dùng giao diện làm cho bóng rơi theo đường chéo, nhưng quả bóng vẫn đứng yên đường ren như không; hoạt động bình thường. Không cần thiết phải tải xuống sân bóng đá, tuy nhiên bạn có thể muốn
Tôi đang sử dụng Jmeter và Ant trong một dự án của mình, khi tôi tạo báo cáo, nó sẽ hiển thị URL, #Samples, Thất bại, Tỷ lệ sai công, Thời gian trung bình, Thời gian tối thiểu, Thời gian tối đa trong báo cáo. report.
Tôi có một vấn đề bất ngờ và hy vọng ai đó có thể giúp tôi. bằng Canvas (android) nhưng tôi không biết cách thực hiện. hình giống hình tam giác hơn, có đầu lớn hơn
Câu hỏi này đã có câu trả lời: Kiểm tra mức độ nghiêm trọng của các dạng bằng JavaFX (1 câu trả lời) Đã đóng 8 năm trước. Tôi đang sử dụng thư viện JavaFx 8. Nhiệm vụ của tôi rất đơn giản: Tôi muốn kiểm tra
Cách chia tỷ lệ phần trăm của tập tin được đánh giá. (60%/20%/20% phần), tôi có thể thực hiện công việc này theo cách thủ công, -_-: $ wc -l brown.txt 57339 brown.tx
You can help Làm cách nào để tôi đạt được kết quả mong muốn? Tôi có thể làm gì với Bootstrap?
Tôi hiện đang xây dựng một trang web và gặp sự cố với tỷ lệ biến đổi. có hai điều xảy ra: Nền "quét" theo đường Góc Nhãn nút thay đổi màu thay đổi một chút
Tôi cần vẽ sơ đồ của một số lượng lớn dữ liệu bằng cách sử dụng các đường thẳng và biến thể được phép Change affine (chia tỷ lệ biểu đồ để phù hợp với chế độ xem). không có kết quả (vì các điểm được sao chép vào đường dẫn trước khi vẽ).
Tôi đang sử dụng trình phát hiện tính năng HOG dựa trên SVM phân loại. Vì thế sau: Áp dụng bộ dò HOG trên ảnh thang độ xám để cắt vùng màu được phát hiện
Tôi có hình ảnh sau: Tôi muốn điền vào đường viền của nó (tức là tôi muốn điền các dòng vào hình ảnh này). đã cố gắng đóng cấu hình nhưng sử dụng hạt nhân hình chữ nhật có kích thước 3x3 và 10 lần lặp không đầy đủ đường viền.
Tôi phải tìm một thuật toán có thể tìm tổng số giao điểm giữa hai mảng tập hợp, một số đã được nhận sắp xếp. point.
Nói một cách đơn giản - Tôi muốn vẽ một tia/đường thẳng từ Thiết cắt gần đến mặt cắt xa bằng cách sử dụng phối cảnh được phép. bằng một cú nhấp chuột bằng các phương pháp được mô tả trong các đồ họa/OpenGL hướng dẫn khác nhau. vấn đề tôi đang gặp phải là đèn của tôi phải như
Tôi là một lập trình viên xuất sắc, rất xuất sắc!