Multithreaded programing



Lý thuyến và thực hành khác xa nhau 🙂

Lập trình đa luồng (multithreading) là không hề đơn giản, chúng ta dù junior hay senior hay expert đều phải công nhận điều đó. Xoay quanh xử lý đa luồng là cả một tá những vấn đề như: asynchronous, dead locking, memory leaks, lock/wait-free algorithms (mutex, semaphore). Nhiều trường hợp dở khóc dở cười như yêu cầu cho chương trình là 2Gb RAM nhưng bắt buộc phải cắm thêm 4GB mới chịu chạy, có chương trình thì cứ chạy một lúc là RAM và CPU lên 100%, hay có những case hóc búa hơn là scheduling cứ đêm hệ thống mới báo về 100% RAM và CPU và sáng ra thì máy ngủ chưa dạy… rất nhiều trường hợp khác nữa

Ở những ngôn ngữ lập trình bậc thấp như C, C++ thì còn vất vả hơn nhiều vì nó không được hỗ trợ Garbage Collector, Concurence như ở những ngôn ngữ lập trình bậc cao như C#, Java, Python… một thứ mà giúp chúng ta quản lý tốt hơn về tài nguyên tốt hơn.

Bạn hãy dành mấy giây để ngó qua bức tranh về những con cún tranh nhau đồ ăn và xung đột xảy ra. Điều đó có nghĩa là việc ai người đó làm thì chẳng sao, hễ cứ động vào tài nguyên chung là xảy ra xung đột, nó giống như việc các threads cùng giành giật một tài nguyên vậy.
Một trong những kỹ thuật chính trong xử lý đa luồng là Mutex và Semaphore, liên tưởng tới câu chuyện về nhà vệ sinh (toilet):

Mutex: Có 1 cái toilet và 1 cái chìa khóa, ai mà có chìa khóa vào toilet là chiếm luôn lấy cái nhà vệ sinh khi giải quyết xong thì mới đưa cái chìa khóa cho người tiếp theo trong hàng đợi. Kể cả ông đợi ở bên ngoài xảy ra sự cố nặng mùi cũng mặc

Semaphore: giả sử chúng ta có 4 toilets và có 4 keys tương ứng để mở cửa, semaphore sẽ đếm ngược (count down) bắt đầu từ 4 -> 3 -> 2->1. Cứ một người vào toilet thì giảm đi 1 key, nếu toilet là full rồi thì không còn key nào lúc đó semaphore count = 0. Khi một người giải quyết xong và trả lại key thì semaphore tăng lên 1 và người ở hàng đợi tiếp theo sẽ được vào giải quyết.
Những ngôn ngữ bậc trình bậc cao như C#, Java, Python, Ruby on Rail đã có sẵn các thư viện xử lý đồng thời (concurrence) rồi, các thư viện này đã build-in luôn các lock/wait-free algorithms vào đó nhưng việc lựa chọn và dùng nó phải hiểu bản chất.

Những hệ thống giao dịch tài chính không cho phép chương trình có độ trễ nhiều, một sàn giao dịch chứng khoán có thể phải xử lý vài trăm ngàn, thậm trí vài chục triệu lệnh mua bán mỗi giây. Các hệ thống này đòi hỏi communicate giữa các threads phần lớn là bất đồng bộ (asynchronous) độ trễ được tính bằng tổng thời gian xử lý mỗi nghiệp vụ sau đó trừ đi communication cost ( communication cost là những con số được ví như tốc độ đọc ghi của L1/ L2/ L3 cached, RAM, SSD, HDD LAN, mutex lock/unlock … các bạn có thể tham chiếu những con số này ở phần Note trên Gravity Model)

Những năm trở lại đây message queues được các hệ thống này áp dụng nhiều hơn với sự ra đời của các thư viện như: RabbitMQ, ActiveMQ, ZeroQueue … giúp cho việc giao tiếp giữa 2 processes, 2 services tốt hơn, ổn định hơn và có khả năng phân tán khi cần.

Ở bài này mình giới thiệu với các bạn về một số kiến thức cơ bản về Muti-threading, hy vọng bài viết giúp ích được cho ai đó trong số chúng ta.

Hãy LIKE/SHARE/Comment tới Gravity Model page để chúng ta thảo luận thường xuyên hơn. 
Hãy tới thăm Gravity Model còn rất nhiều bài viết hay đang chờ bạn ở đó và nếu bạn có câu hỏi gì đừng ngại inbox cho Gravity Model.

Thanks you!

Yhoang,

#Multithreading
#Mutex
#Semaphore
#ActiveMQ
#RabbitMQ
#ZeroQueue

Please follow and like us:

Leave a Reply

Your email address will not be published. Required fields are marked *