Concurrency – Chen chúc nhau, ai sẽ là người được ưu tiên

Concurrency – Chen chúc nhau, ai sẽ là người được ưu tiên

May 6, 2022 3 By Ntech Developers

Dịp nghỉ lễ vừa rồi chắc hẳn ai cũng cảm nhận được thế nào là đặc sản tắc đường ở trung tâm các thành phố lớn. Nhân dịp thấy mọi người chen nhau vui như vậy mình xin lấy nó làm ví dụ cho loạt bài sắp tới này của mình về lập trình bất đồng bộ cũng như xử lý đồng thời trong kiến trúc phần mềm.

Đối với bài viết này là sự mở đầu cho loạt bài viết trên mình giới thiệu cho mọi người một cái nhìn tổng quát cùng với định nghĩa về Concurrency.

Trong thực tế vấn đề sự việc, hoạt động, con người diễn ra một cách đồng thời là một điều không có gì là xa lạ đối với chúng ta. Chẳng hạn như, các xe máy các xe ô tô cùng đi trên một con đường từ điểm A tới điểm B một cách đồng thời. Chúng ta cùng đến công ty có thể lệch nhau một vài tiếng nhưng mà cũng đều được diễn ra một cách song song trên một hành tinh này. Hay đơn gian như việc các các quầy thu ngân diễn ra trong siêu thị hằng ngày cũng được diễn ra một cách đồng thời để giúp cho việc thanh toán của mỗi chúng ta được diễn ra nhanh hơn. Đó chính là những ví dụ trong đời thực của Concurrency.

Còn đối với phần mềm thì sao, bạn đã từng nhìn thấy một thông báo từ ban giám đốc gửi tới toàn thể nhân viên cùng một thời điểm chưa, bạn từng nghĩ có rất nhiều người săn sale vào 12h đêm thì hệ thống thương mai điện tử sẽ diễn ra như thế nào vào cùng một thời điểm đó. Hay những sàn đấu giá, đặt chỗ, đặt cọc diễn ra online nhưng có hàng nghìn người cùng tranh nhau một bất động sản nào đó thì hệ thống sẽ phải xử lý như thế nào. 

Các bài toán từ thực tế đến hệ thống phần mềm trên đều có một điểm chung đó là tính chất đồng thời của một sự việc.

Đi sâu hơn một chút thì mặc dù tiếng việt mình đều dịch là đồng thời nhưng có một số từ khóa chuyên ngành mà bạn cần phân biệt để tránh sự hiểu nhầm.

Concurrency (xử lý đồng thời) nghĩa là có khả năng giải quyết nhiều công việc một lúc, và những công việc đó không nhất thiết phải xảy ra tại cùng một thời điểm.

Parallelism (song song) nghĩa là có khả năng xử lý nhiều công việc tại cùng một thời điểm.

Thread (luồng): là một chuỗi các lệnh được lập trình một cách nhỏ nhất để có thể được quản lí độc lập trong một bộ định thời. 

– Multithreading (đa luồng): liên quan tới việc sử dụng nhiều thread cùng lúc. Đó là 1 dạng của concurrency, nhưng không phải là dạng duy nhất.

Mình không muốn đi sâu quá vào phân biệt những khái niệm này, bạn đọc có thể dựa vào từ khóa để tìm hiểu thêm. Ở đây mình chỉ muốn đề cập đến tính chất đồng thời mục đích mở ra một số hướng giải quyết vấn đề cho những bài viết sắp tới mà thôi.

– Concurrency and lock
– Queue
– Batch processing
– Background job
– Cronjob
– Event-driven

Concurrency và những vấn đề nảy sinh

– Priority issue

Như đề đã nhắc đến, nếu các tác vụ diễn ra đồng thời, khi làm việc với concurrency bạn sẽ phải giải quyết rất nhiều vấn đề liên quan, điển hình như là mức độ ưu tiên Priority. Các tác vụ diễn ra đồng thời bạn không thể nào biết trước được tác vụ nào mới là cái hoàn thành trước, tác vụ nào là cái hoàn thành sau. Vậy nên bạn sẽ phải tổ chức làm sao để có thể control được thứ tự ưu tiên trước sau. 

Ví dụ như khi vào quầy thanh toán, sẽ luôn có những quầy dành riêng cho người già, trẻ em, bà bầu hay những người mua số lượng hàng hóa ít dưới 5 món. Đây là một cách đánh giá mức độ ưu tiên của concurrency.

– Race condition

Race condition là trạng thái mà hai hay nhiều luồng (thread) cùng truy xuất, thay đổi tài nguyên dùng chung (shared resource) một cách đồng thời. Tài nguyên dùng chung (shared resource) ở đây có thể là một thuộc tính (property), một object, một file, memory… 

Bất cứ mọi tài nguyên dùng chung nào mà được chia sẽ giữa nhiều thread đều tìm ẩn nguy cơ xung đột (conflict). Vấn đề race condition luôn diễn ra nếu nhiều thread truy cập tài nguyên dùng chung mà không đảm bảo rằng một thread đã kết thúc các hoạt động trên tài nguyên dùng chung trước khi một thread khác bắt đầu truy xuất nó.

Ví dụ, hai bác nông dân cùng làm đi cày nhưng lại chỉ có một con trâu mà thôi. Vậy hai bác ý không thể đi cày cùng một lúc được trong khi chỉ có một phương tiện làm việc dùng chung. 

– Mutual exclusion

Cách truy cập mà chỉ có một thread tại một thời điểm truy cập tới một tài nguyên nhất định được gọi là Mutual Exclusive Access.

Để đảm bảo điều này, mỗi thread mà muốn truy cập một tài nguyên phải có một cái khoá (mutex lock). Một khi thread này kết thúc hoạt động, nó trả lại cái khoá và một thread khác lấy nó để truy cập.

Nhưng vấn đề là khóa khi nào, mở khi nào, và nếu chẳng may khóa bị hỏng thì điều gì sẽ xảy ra.
Mình sẽ đề cập đến Lock ở bài viết sau nhé!

Vẫn là ví dụ hai bác nông dân dùng chung một con trâu kia, hai bác sẽ phải phân công lịch làm việc để sao cho sử dụng con trâu không bị trùng vào một thời điểm. Khi người này dùng phương tiện để làm nông thì người kia sẽ nghỉ và ngược lại.

– Dead lock issue

Mutex locks giải quyết vấn đề race condition nhưng không may nó lại nảy sinh ra một vấn đề khác là deadlock. Một deadlock diễn ra khi nhiều thread đang đợi lẫn nhau để hoàn thành (finish) công việc dẫn tới tắc nghẽn (stuck).

Có khá nhiều ví dụ cho dead lock nhưng bạn hãy hình dung ai cũng muốn sử dụng tài nguyên tuy rằng phân theo thứ tự rồi nhưng người sử dụng đầu tiên không chịu nhả tài nguyên dùng chung ra hoặc họ không biết có bao nhiêu người đang chờ tài nguyên hay không thì những người phía sau sẽ gặp phải tình trạng nằm đợi dài người.

– Race limit issue

Khi làm việc với concurrency một vấn đề nữa mà bạn phải quan tâm đó là giới hạn luồng xử lý. Giả sử như hệ thống của chúng ta nhận được hàng nghìn request nhưng mà trong số đó chỉ xử lý được trăm requests chẳng hạn, khi đó số request còn lại thì bị lỗi do CPU hệ thống đang quá tải.

Ví dụ thực tế rõ rất đó chính là đường xá việt nam mùa lễ hay những giờ tan tầm chẳng hạn, các cửa ngõ, ngã ba ngã tư sẽ bị quá tải khi lưu lượng xe di chuyển quá nhiều trong cùng một thời điểm dẫn tới tắc đường kẹt xe.

Trên đây là những vấn đề bạn nên hiểu và suy nghĩ những cách giải quyết khi làm việc với concurrency. Hi vọng bài viết này có thể giúp ích cho bạn cái nhìn tổng quát về cụm từ “đồng thời” với những ví dụ cụ thể và rất đặc trưng. Mình không đề cập tới cụ thể bất cứ ngôn ngữ nào cũng như cách xử lý trong từng ngôn ngữ. Trước đó mình cũng có đề cập đến concurrency trong loạt bài viết về performance test spiderum rồi, bạn có thể tìm đọc lại để hiểu thêm về từ khóa này nhé!

#ntechdevelopers