Đa luồng

Python SELF VI
Mức độ , Bài học
Có sẵn

1.1 Lịch sử ra đời

Con người thường xuyên có ý tưởng tạo ra những dự án hoành tráng mới, nhằm vượt qua mọi dự án hoành tráng trước đó. Kim tự tháp Khufu ở Giza - lớn nhất, Burj Khalifa ở Dubai - cao nhất, và Vạn Lý Trường Thành - dài nhất.

Tuy nhiên, tổ chức công việc cho những dự án như vậy rất khó khăn. Nếu xây dựng kim tự tháp mới gấp đôi chiều cao, nó sẽ cần gấp tám lần lượng đá. Nghĩa là, cần nâng cao hiệu suất mỏ đá hoặc mở thêm nhiều mỏ.

Cũng cần tìm gấp tám lần số kỹ sư, có thể mở các trường kỹ thuật, chuẩn hóa bản vẽ, hình học, chữ viết. Tóm lại, đây là một bài toán không dễ giải...

Trải qua hàng nghìn năm từ khi xây dựng kim tự tháp, không có gì thay đổi - con người tiếp tục suy nghĩ làm thế nào để hoàn thành nhiều công việc hơn trong thời gian ngắn hơn. Và khi máy tính được phát minh, bài toán này đã được giải quyết bởi những bộ não xuất sắc nhất của loài người.

Làm thế nào để hoàn thành chương trình nhanh gấp mười lần? Có vẻ như một câu hỏi kỳ lạ - nếu bộ xử lý đã hoạt động với tốc độ tối đa, có lẽ không thể. Tuy nhiên, tôi không ngẫu nhiên nhắc đến những bộ não xuất sắc nhất của loài người. Họ đã phân tích công việc của tất cả các chương trình và đi đến kết luận rằng có ba hướng lớn để phát triển.

Loại bỏ thời gian chết

Hóa ra, phần lớn thời gian chương trình chờ đợi. Nó luôn chờ đợi điều gì đó: dữ liệu cần được sao chép từ một vị trí trong bộ nhớ đến vị trí khác, tải từ ổ cứng vào bộ nhớ, chờ đáp ứng từ máy chủ trên yêu cầu, nhập dữ liệu từ người dùng, v.v.

Tất cả những nhiệm vụ này không được thực hiện bởi bộ xử lý trung tâm mà bởi các bộ điều khiển bộ nhớ, ổ cứng, v.v. Và bộ xử lý trung tâm trong thời gian này có thể được tải bằng một công việc hữu ích khác. Vì vậy, ý tưởng xuất hiện để chạy nhiều hơn một luồng thực thi lệnh (thread) trong một bộ xử lý.

Và trong khi, ví dụ, một luồng chờ đợi nhập dữ liệu từ người dùng, luồng thứ hai tải gì đó từ mạng, luồng thứ ba xử lý dữ liệu, luồng thứ tư vẽ lên màn hình hình ảnh. Rồi sau đó, nó tiến hóa thành các tác vụ không đồng bộ và coroutine, nhưng đó là một câu chuyện khác.

Nhiều chương trình hơn

Nếu các chương trình chờ đợi 80% thời gian, thì tất nhiên đó là điều không tốt. Ngược lại, không thể viết lại tất cả các chương trình theo cách tiếp cận mới của chúng ta. Có lẽ, vấn đề này có thể được giải quyết một cách khác - có thể chỉ cần chạy trên máy tính nhiều chương trình cùng một lúc.

Trong trường hợp này, hệ điều hành giám sát công việc của các chương trình, và nếu chương trình chờ đợi, nó sẽ chuyển thời gian thực thi cho chương trình khác. Sự chuyển đổi này diễn ra hàng chục lần mỗi giây, và người dùng không để ý đến sự chuyển đổi - từ góc độ của họ, các chương trình chạy đồng thời.

Nhiều bộ xử lý hơn

Thực hiện đồng thời các chương trình là tuyệt vời, nhưng nếu có quá nhiều chương trình, và chúng chờ đợi ít? Không có thời gian chết - không có sử dụng hiệu quả. Ví dụ, chúng ta có mười chương trình cần tính toán, hoặc một trò chơi đầy đủ tài nguyên và thêm một số thứ khác cùng với nó.

Giải pháp cho vấn đề này là thêm vào bộ xử lý nhiều bộ xử lý. Để tránh nhầm lẫn, họ gọi chúng là lõi. Bây giờ chúng ta có các bộ xử lý, mà có nhiều lõi (sub-processor), trên đó hàng chục chương trình chạy đồng thời.

Thú vị! Số lượng lõi trong bộ xử lý

Ngày nay, các bộ xử lý máy chủ có thể có từ 64 đến 256 lõi, và trong một số trường hợp chuyên biệt thậm chí nhiều hơn. Ví dụ, các bộ xử lý AMD EPYC thế hệ 4 cung cấp lên đến 96 lõi, và IBM POWER10 có thể có lên đến 240 lõi trên một chip. Bộ xử lý người dùng cũng đã tiến hóa đáng kể: CPU máy tính để bàn hiệu suất cao như AMD Threadripper có thể có lên đến 64 lõi, trong khi các mẫu phổ biến hơn thường có từ 6 đến 16 lõi.

Tiếp theo là gì? Vẫn còn nhiều chỗ để phát triển! Đầu tiên, một bo mạch chủ máy chủ có thể lắp nhiều bộ xử lý, ví dụ hai hoặc thậm chí bốn bộ. Thứ hai, các máy chủ có thể được kết nối thành các rack máy chủ với 10-20 cái. Và các rack máy chủ thành trung tâm dữ liệu, nơi có hàng ngàn rack.

Hệ thống phân tán và kiến trúc microservices đã trở thành thực hành phổ biến trong phát triển phần mềm hiện đại. Nhiều công ty lớn, như Google, Amazon, Netflix, và cả các doanh nghiệp nhỏ hơn, sử dụng hệ thống phân tán để xử lý lượng dữ liệu lớn, đảm bảo tính khả dụng cao và khả năng mở rộng của dịch vụ. Những hệ thống này cho phép sử dụng hiệu quả tài nguyên của nhiều máy chủ, làm việc cùng nhau như một thể thống nhất, điều này nâng cao đáng kể hiệu suất và độ bền bỉ của ứng dụng.

1.2 Lợi ích

Đa luồng, hay thực hiện đồng thời các nhiệm vụ trong một chương trình, có một số lợi ích chính, có thể cải thiện đáng kể hiệu suất và hiệu quả của phần mềm. Hãy xem xét những lợi ích chính của đa luồng.

1. Tăng hiệu suất và tốc độ thực hiện

Thực hiện song song các nhiệm vụ: Đa luồng cho phép thực hiện đồng thời nhiều nhiệm vụ, điều này đặc biệt hữu ích cho các chương trình yêu cầu thực hiện nhiều hoạt động độc lập. Điều này giúp tăng tốc độ thực hiện chương trình, vì các nhiệm vụ được thực hiện song song, sử dụng tất cả tài nguyên xử lý có sẵn.

Sử dụng bộ xử lý đa lõi: Bộ xử lý hiện đại có nhiều lõi, và đa luồng cho phép sử dụng toàn bộ sức mạnh của chúng, phân phối các luồng đến các lõi khác nhau để thực hiện nhiệm vụ song song.

2. Cải thiện sự phản hồi và tương tác với người dùng

Nhiệm vụ nền: Đa luồng cho phép thực hiện các hoạt động kéo dài hoặc tiêu tốn tài nguyên trong chế độ nền, trong khi đó giữ luồng chính, chịu trách nhiệm cho giao diện người dùng, vẫn phản hồi. Điều này cải thiện trải nghiệm người dùng, vì giao diện không bị khóa khi thực hiện các nhiệm vụ nặng.

Các hoạt động không đồng bộ: Tương tác với người dùng và xử lý sự kiện có thể diễn ra song song với thực hiện các nhiệm vụ chính, làm cho ứng dụng trở nên phản hồi và hiệu quả hơn.

3. Sử dụng tài nguyên hệ thống hiệu quả

Tối ưu hóa tài nguyên: Đa luồng cho phép sử dụng hiệu quả hơn tài nguyên hệ thống, như thời gian xử lý và bộ nhớ. Điều này đặc biệt quan trọng đối với máy chủ và hệ thống tính toán hiệu suất cao, nơi đa luồng cho phép xử lý một lượng lớn yêu cầu và nhiệm vụ đồng thời.

Quản lý nhập-xuất: Ứng dụng đa luồng có thể quản lý nhiệm vụ nhập-xuất (ví dụ, các hoạt động mạng, đọc và ghi tập tin) hiệu quả hơn, vì các luồng có thể thực hiện các nhiệm vụ khác, trong khi một trong số chúng chờ đợi hoàn thành hoạt động nhập-xuất.

4. Hỗ trợ đa nhiệm

Đa nhiệm: Đa luồng cho phép thực hiện nhiều nhiệm vụ đồng thời trong một tiến trình, điều này đơn giản hóa việc phát triển ứng dụng yêu cầu đa nhiệm, như máy chủ web, cơ sở dữ liệu và ứng dụng thời gian thực.

Xử lý song song dữ liệu: Trong các nhiệm vụ liên quan đến xử lý lượng lớn dữ liệu, đa luồng cho phép chia dữ liệu thành các phần và xử lý chúng song song, đẩy nhanh quá trình thực hiện nhiệm vụ.

Ví dụ về sử dụng đa luồng

Máy chủ web: Đa luồng cho phép máy chủ web xử lý nhiều yêu cầu từ khách hàng cùng lúc, tăng hiệu suất và khả năng mở rộng của các máy chủ.

Giao diện đồ họa người dùng (GUI): Trong các ứng dụng giao diện đồ họa, đa luồng cho phép thực hiện tính toán kéo dài trong chế độ nền, giữ cho giao diện phản hồi.

Tính toán khoa học: Đa luồng được sử dụng để xử lý song song dữ liệu trong các tính toán khoa học, giúp tăng tốc độ thực hiện các nhiệm vụ tính toán phức tạp.

Trò chơi và mô phỏng: Trong trò chơi, đa luồng cho phép xử lý đồng thời vật lý, đồ họa, âm thanh và hành động của người dùng, cải thiện hiệu suất và sự chân thực.

1.3 Tên gọi đúng

Tên gọi “đa luồng” có một số phàn nàn. Nó bao gồm hai từ: “nhiều” và “luồng”, như ám chỉ rằng trong chương trình có nhiều “luồng thực thi lệnh”, đang thực hiện gì đó.

Đó là một so sánh đẹp, nhưng trong tài liệu tiếng Anh (gốc) để chỉ các hành động thực hiện song song, họ sử dụng thuật ngữ “sợi” (thread). Và, tương ứng, đa luồng được gọi là multi-threading.

Điều này có thể được coi là một sự hiểu lầm nhỏ - ai quan tâm cách các thuật ngữ khác nhau được dịch sang ngôn ngữ khác, nếu trong lập trình không sử dụng mạnh mẽ một thứ gọi là stream, không thể dịch khác ngoại trừ từ “luồng”.

Do đó, hiện nay trong thuật ngữ tiếng Nga có một số nhầm lẫn, họ giải quyết bằng hai cách:

  • Thread (sợi) được dịch là “luồng thực thi [lệnh]”.
  • Stream (luồng) được dịch là “luồng dữ liệu”.

Mặt khác, nhiều lập trình viên chỉ bắt đầu sử dụng các thuật ngữ tiếng Anh mà không dịch:

  • Thread (sợi) được phát âm là “thread”, và multi-threading là “multi-threading”.
  • Stream (luồng) được phát âm là “stream”.

Thread thường được gọi là sợi, nhưng thuật ngữ “multi-threading” lại không được chấp nhận. Do đó, thường trong cuộc trò chuyện sử dụng “sợi” và “đa luồng” cùng lúc.

Sử dụng nhiều thuật ngữ mượn làm cho ngôn ngữ giàu hơn, cho phép các từ có thêm ý nghĩa mới và đơn giản hóa giao tiếp với đồng nghiệp từ các nước khác. Tôi hoàn toàn ủng hộ cách tiếp cận này.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION