NÊN SỬ DỤNG MULTI THREADING THẾ NÀO

Sau khi đã biết cách viết chương trình multi-thread, giờ ta sẽ cùng bàn đến vấn đề quan trọng hơn: Khi nào nên dùng MT, và còn có lựa chọn nào khác nữa không?

ℹ️ Multi threading phù hợp với những trường hợp sau đây:

👉 Chương trình cần tính toán nhiều (sử dụng nhiều năng lực tính toán của CPU) và muốn tận dụng nhiều CPU hoặc core khác nhau, mỗi thread sẽ tính toán một bài toán riêng lẻ. Tuy nhiên lưu ý là không phải cứ tạo thread mới thì nó sẽ tận dụng được các nhân khác, nếu bạn có 2 thread nhưng được gán cho cùng một core/cpu thì hiệu năng cũng sẽ không tăng lên. Với các bài toán này, bạn nên tìm hiểu về các thư viện hỗ trợ lập trình song song trên nền tảng của bạn.Ngay cả khi bạn chỉ có một bài toán cần tính, bạn cũng nên đưa vào một thread chạy ngầm bởi 2 lý do:

– Chương trình sẽ không bị khóa cứng lại và trở nên “not responsive”, người dùng có thể theo dõi tiến độ, hoặc hủy nếu quá trình tính toán quá lâu.

Continue reading “NÊN SỬ DỤNG MULTI THREADING THẾ NÀO”

Chuyên mục trả lời câu hỏi

Trả lời:

Ta có thể hiểu thế này, một tiến trình (process) được tạo ra khi bạn tải và chạy một chương trình từ đĩa, nó sẽ có một không gian địa chỉ riêng, độc lập hoàn toàn với các tiến trình khác. Hai tiến trình sẽ nằm ở hai dải địa chỉ khác nhau, nếu muốn nói chuyện thì phải thông qua một cơ chế giao tiếp IPC nào đó (inter-process communication), như TCP/IP, namepipes… Một thread là một luồng xử lý của CPU, là một dãy lệnh mà CPU sẽ thực thi, dãy lệnh đó hiển nhiên sẽ được nạp vào và nằm bên trong một tiến trình.

Có thể hiểu nôm na, mỗi process là một nhà máy, còn các thread là các công nhân. Hai công nhân làm cùng nhà máy thì có thể truy cập vào các tài nguyên chung, còn khác nhà máy thì buộc phải dùng dịch vụ chuyển phát thì mới trao đổi thông tin được. Một nhà máy thì có ít nhất một công nhân – single thread (nhưng cũng có thể có nhiều hơn – multi thread).

Continue reading “Chuyên mục trả lời câu hỏi”

VẤN ĐỀ ĐỒNG BỘ TRUY CẬP DỮ LIỆU

Bài toán đồng bộ

Đối với các chương trình single-thread, ta không cần quan tâm đến việc đồng bộ, bởi chương trình sẽ thực thi theo thứ tự từ trên xuống dưới từng câu lệnh một, trạng thái của chương trình sẽ chỉ bị thay đổi bởi chính nó. Tuy nhiên với các chương trình multi-thread, sẽ xảy ra trường hợp có nhiều hơn một thread cố gắng truy cập vào cùng một biến và gây ra sai sót.

👉 Xét ví dụ sau khi tráo đổi giá trị hai biến x và y (swap):

x = 10;
y = 20;
t = x; 
x = y; (*)
y = t;

Tại vị trí (*), giá trị của x và y bằng nhau, và bằng 20. Đây có thể coi là một trạng thái sai, bởi chỉ có thể x = 10, y = 20 hoặc x = 20, y = 10 sau khi tráo đổi xong. Trước hay sau khi tráo lại thì x * y cũng phải bằng 200, tuy nhiên tại vị trí (*), x * y sẽ là 400.Nếu có một thread thứ hai đọc giá trị của x và y để xử lý công việc, sẽ có một lúc nào đó giá trị nó đọc được sẽ bị sai.Cũng với ví dụ trên, giả sử có 2 thread cùng thực thi, bởi các câu lệnh có thể ngắt quãng và thực thi xen kẽ bởi các thead khác nhau, nên có thể xảy ra trường hợp sau:(thread 1 ký hiệu t1, thread 2 ký hiệu t2)

Continue reading “VẤN ĐỀ ĐỒNG BỘ TRUY CẬP DỮ LIỆU”

NÓI THÊM MỘT CHÚT VỀ THREAD

Trong các ứng dụng single thread, ta chỉ có duy nhất một thread chạy trong một không gian địa chỉ (1), do vậy ta có thể đảm bảo không ai thay đổi dữ liệu trong suốt quá trình chạy. Tuy nhiên trong các ứng dụng multi-thread sẽ có 2 hoặc nhiều hơn thread chạy đồng thời và chia sẻ chung không gian địa chỉ, do vậy một trong những bài toán quan trọng nhất là đồng bộ dữ liệu dùng chung giữa các thread.

Nên lưu ý khái niệm chạy đồng thời ở đây là tương đối, vì một máy tính có thể chỉ có rất ít CPU, nên nó phải chia sẻ giữa nhiều thread khác nhau. Trong thực tế, số thread luôn lớn hơn số CPU có trong hệ thống, trong một thời điểm có vài trăm đến vài ngàn thread chạy đồng thời là điều bình thường, mỗi thread sẽ chỉ được cấp một khoảng thời gian để chạy (gọi là time slide), sau đó HĐH sẽ lấy lại quyền điều khiển và chuyển sang thread khác.

Continue reading “NÓI THÊM MỘT CHÚT VỀ THREAD”

THREAD POOL

Khi mới học viết các ứng dụng multi thread, mỗi khi cần xử lý một công việc song song, ta thường làm theo cách sau:

– Tạo một thread mới.

– Truyền tham số khởi tạo và cho thread chạy để xử lý công việc.

– Kết thúc thread và nhận kết quả.

Một trong những bài toán phổ biến nhất cho người mới bắt đầu là viết ứng dụng chat(*). Và cách làm cũng tương tự như trên:

– Mở server socket và listen trên server socket đó.

– Mỗi khi có một client kết nối mới, bạn sẽ tạo một thread để chờ dữ liệu trên kết nối đó, nếu có thì xử lý, hoặc gửi dữ liệu cho đầu bên kia thông qua socket.

– Khi hai bên hoàn thành công việc, ngắt kết nối và kết thúc thread.

👉 Cách làm này khá đơn giản, nhưng có một số nhược điểm như sau:

Continue reading “THREAD POOL”

LẬP TRÌNH MULTI THREAD

Vậy là ta đã xong OOP, con trỏ và các phần nói về quản lý bộ nhớ, giờ tiếp đến một chủ đề nữa: lập trình đa luồng – multi thread programming.Trong bài này tôi chỉ giới thiệu qua các khái niệm cơ bản và các từ chuyên ngành liên quan, để dễ nhất các bạn nên đọc lại những bài viết về chủ đề quản lý bộ nhớ (stack, heap) và bài về từ khóa virtual trong OOP.

ℹ️ Trước tiên ta cần hiểu thread là gì

Về kỹ thuật, một thread là một chuỗi các lệnh cần được thực thi bởi CPU, hay ta có thể tưởng tượng một thread là một function, trong đó chứa các lệnh thực thi, và quan trọng nhất – nó sẽ chạy ĐỒNG THỜI với chương trình chính.Bạn có thể thấy, chương trình sẽ bắt đầu bằng hàm main, Main, hay với nhiều ngôn ngữ là từ câu lệnh đầu tiên. Mỗi khi bạn gọi một function, bạn sẽ phải chờ nó kết thúc, giờ mỗi khi gọi một hàm, nó sẽ được thực thi bởi một CPU khác, vì ta có 2 CPU nên hàm chính và hàm được gọi sẽ chạy đồng thời với nhau.

❓Bạn sẽ đặt câu hỏi: Nếu máy của tôi chỉ có 1 CPU, vậy làm sao tôi có thể chạy đa luồng được?

ℹ️ Đó là nhiệm vụ của hệ điều hành, với các hệ điều hành đa nhiệm (multi tasking OS), nó sẽ có những cách sau để cho phép bạn chạy 2 thread cùng lúc.

Continue reading “LẬP TRÌNH MULTI THREAD”