- vừa được xem lúc

010: Nhầm tưởng về Data race và Race condition?

0 0 45

Người đăng: Dat Bui

Theo Viblo Asia

Bài viết nằm trong series Multithread từ hardware tới software với Java.

Hai vấn đề data racerace condition hay bị đánh đồng là một (có lẽ vì cùng từ race). Tuy nhiên nó diễn tả hai vấn đề khác nhau trong lập trình multi-thread.

Google search, gần như không có bài tiếng Việt nào phân biệt về hai khái niệm này và đa số coi chúng như nhau, thậm chí không tồn tại khái niệm data race. Do đó, học tốt ngoại ngữ và đặc biệt là tiếng Anh sẽ giúp ích rất nhiều cho con đường hiện tại và sau này của chúng ta.

Lưu ý, không phải nguồn nào cũng chính thống và bài viết nào cũng đúng. Hãy đọc, phân tích và lựa chọn sự đúng đắn. Cũng đừng vội tin những gì mình chia sẻ mà hãy kiểm chứng.

Hơi lan man, bài trước chúng ta đã nắm rõ về data race, hôm nay sẽ tìm hiểu về khái niệm còn lại là race condition và xem chúng khác nhau như thế nào. Let's begin.

Race condition

Quay lại khái niệm của data race, nó xảy ra khi:

  • Từ 2 thread/process trở lên cùng truy cập vào vùng nhớ chung (shared resource).
  • Ít nhất 1 thread/process thay đổi giá trị của vùng nhớ chung đó.

Do đó, vấn đề gặp phải có thể là:

  • Các giá trị ghi đè lẫn nhau.
  • Đọc ra sai giá trị.

Việc xử lý data race không phức tạp, chỉ cần đảm bảo một thread được truy cập vào critical section tại một thời điểm, sử dụng cơ chế mutual exclusion.

Tuy nhiên, với cách làm trên chỉ đảm bảo không có data race, nhưng không ngăn chặn được race condition. Cụ thể, race condition nói về:

  • Vấn đề sai sót về mặt thời gian hoặc thứ tự thực thi của các thread trong chương trình khiến cho kết quả cuối cùng không đúng như mong muốn.

Trong thực tế, race condition xảy ra do data racedata race dẫn đến race condition. Không khác nhau lắm nhỉ ?, tuy nhiên hai vấn đề này không phụ thuộc vào nhau.

  • Một chương trình có thể có data race mà không có race condition.
  • Hoặc có race condition mà không có data race.

Loằng ngoằng thật, nhảy vào ví dụ cho dễ hình dung.

Thời buổi Covid, phải luôn đeo khẩu trang để bảo vệ bản thân và những người xung quanh nhé. Oh, mình chợt nhận ra trong kho chỉ còn một hộp. Mình chuẩn bị đi chợ, đã lên danh sách mua đồ, tiện thể mua thêm vài hộp khẩu trang.

Mình và bà xã sẽ đóng vai 2 thread, danh sách mua đồ là shared resource, đã có sẵn 1 hộp khẩu trang rồi. Cây bút đại diện cho mutex.

Mình nghĩ mua thêm 3 hộp là đủ, mình lấy bút (đảm bảo không xảy ra data race), sửa lại từ 1 thành 4. Con gái tính thích mua sắm, vợ mình phải mua gấp 3 mới thích. Sau khi mình viết xong, cô ấy lấy cây bút và sửa từ 4 thành 12. Chốt deal, mua 12 hộp khẩu trang. Hoàn toàn không xảy ra data race, duy nhất 1 thread đọc ghi tại 1 thời điểm.

Hình như chưa có vấn đề gì, hãy để ý khi ta đổi ngược thứ tự thực hiện. Vợ mình lấy cây bút trước, sửa từ 1 thành 3 (1 * 3). Sau đó đến lượt mình và sửa từ 3 thành 6 (3 + 3). Chốt deal, mua 6 hộp khẩu trang.

Ố ồ, mặc dù đã sử dụng cây bút là mutext thực hiện việc truy cập đến danh sách mua sắm là shared resource đảm bảo không xảy ra data race. Tuy nhiên kết quả cuối cùng với mỗi cách thực hiện lại khác nhau vì ta không kiểm soát được thứ tự và số lần thực thi của các thread. Đó chính là race condition.

Chờ chút, tại sao không kiểm soát được số lần thực thi của thread? Bài trước mình có đề cập đến Thread starvation. Nếu trong cả 2 lần thực thi trên, mình không được thực hiện lần nào, kết quả sẽ là 1 * 3 * 3 = 9 hộp khẩu trang. Kết quả không giống 2 lần trước.

Data racerace condition là hai vấn đề khác nhau! Có race condition nhưng không có data race.

Ví dụ về data race mà không có race condition thì sao? Đơn giản thôi, là bài toán rút tiền ở ATM (bài trước).

Trong thực tế, không dễ để phát hiện ra race condition vì vấn đề liên quan đến thứ tự thực hiện các thread, và tất nhiên OS sẽ làm điều đó.

Bạn có thể chạy đúng hàng trăm lần, test hàng nghìn lần và không có vấn đề gì xảy ra. Nhưng một ngày đẹp trời, nó xảy ra và làm sai lệch kết quả chương trình. Những bug tiềm tàng đó được gọi với cái tên Heigenbug (có bạn nào là fan của Breaking Bad không nhỉ).

Thời sinh viên mình đã từng gặp case nếu thêm System.out.println() thì chương trình chạy đúng kết quả, nhưng bỏ đi thì chạy sai (smell vãi ?).

Với Java, có một vài cách để kiểm soát được thứ tự thực thi của thread. Lưu ý, chỉ đảm bảo thứ tự thực thi trước sau của thread chứ không chắc chắn thread được thực thi khi nào. Từ đó giải quyết được vấn đề race condition.

Bài sau mình sẽ trình bày chi tiết ngăn chặn race condition.

Reference

After credit

Với single thread, có khả năng xảy ra data race không?

Bản chất của data race là đọc sai giá trị trong shared resource. Trong một chương trình, nếu 2 thread cùng đọc/ghi vào shared resource (không sử dụng mutex) sẽ có khả năng xảy ra data race.

Vậy với single thread làm sao có thể xảy ra data race được? Mấu chốt là nếu 2 chương trình single thread chạy đồng thời với nhau, cùng thực hiện đọc/ghi và shared resource ví dụ như: file, database... thì hoàn toàn có khả năng xảy ra data race.

Như vậy data race có khả năng xảy ra với single thread. Đi phỏng vấn mà được hỏi như vậy, cứ mạnh dạn trả lời như trên nhé ?.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Hành trình AI của một sinh viên tồi

Mình ngồi gõ những dòng này vào lúc 2h sáng (chính xác là 2h 2 phút), quả là một đêm khó ngủ. Có lẽ vì lúc chiều đã uống cốc nâu đá mà giờ mắt mình tỉnh như sáo, cũng có thể là vì những trăn trở về lý thuyết chồng chất ánh xạ mình đọc ban sáng khiến không tài nào chợp mắt được hoặc cũng có thể do mì

0 0 148

- vừa được xem lúc

Học Regular Expression và cuộc đời bạn sẽ bớt khổ (Updated v2.2)

. Regular Expression (RegEx) à? Nghe quen quen. . Bạn cần xử lý validate (kiểm tra tính hợp lệ) các trường dữ liệu nhập vào ô Text. .

0 0 109

- vừa được xem lúc

Performance Optimization 101: Những câu hỏi cơ bản

Definitive guide for performance engineer. API của bạn có thời gian phản hồi quá lâu. Hay hoá đơn cloud đập vào mặt bạn những con số quá kinh khủng dùng mới chỉ có một nhúm người dùng. HÃY ĐỌC TIẾP, BÀI VIẾT NÀY LÀ DÀNH CHO BẠN.

0 0 63

- vừa được xem lúc

[Deep Learning] Key Information Extraction from document using Graph Convolution Network - Bài toán trích rút thông tin từ hóa đơn với Graph Convolution Network

Các nội dung sẽ được đề cập trong bài blog lần này. . Tổng quan về GNN, GCN. Bài toán Key Information Extraction, trích rút thông tin trong văn bản từ ảnh.

0 0 219

- vừa được xem lúc

Caching đại pháp 1: Nấc thang lên level của developer

Bí quyết thành công trong việc đáp ứng hệ thống triệu user của những công ty lớn (và cả công ty nhỏ). Tại sao caching lại là kỹ thuật tối quan trọng để phù phép ứng dụng rùa bò của chúng ta thành siêu phẩm vạn người mê.

0 0 82

- vừa được xem lúc

Con đường AI của tôi

Gần đây, khá nhiều bạn nhắn tin hỏi mình những câu hỏi đại loại như: có nên học AI, bắt đầu học AI như nào, làm sao tự học cho đúng, cho nhanh, học không bị nản, lộ trình học AI như nào... Sau nhiều lần trả lời, mình nghĩ rằng nên viết hẳn một bài để trả lời chi tiết hơn, cũng như để các bạn sau này

0 0 157