2012-06-19 34 views
26

Tôi đang sử dụng C++ std::atomic_flag làm cờ Boolean nguyên tử. Đặt cờ thành true hoặc false không phải là một vấn đề nhưng làm thế nào để truy vấn trạng thái hiện tại của cờ mà không cần đặt nó vào một giá trị nào đó? Tôi biết rằng có các phương pháp 'atomic_flag_clear' và 'atomic_flag_set'. Họ trả lại trạng thái trước đó nhưng cũng sửa đổi trạng thái hiện tại. Có cách nào để truy vấn trạng thái cờ mà không sửa đổi nó hay tôi phải sử dụng đầy đủ 'std::atomic<bool>'.Trạng thái truy vấn C++ atomic_flag

+1

Nó sẽ xuất hiện rằng việc sử dụng duy nhất của nó là để có được một phương tiện để có được một khóa. Bạn có thể sử dụng 'std :: atomic_flag' làm khóa mà bạn có thể có được trước khi truy cập tài nguyên được chia sẻ, nhưng nếu tài nguyên được chia sẻ đó chỉ là' bool' thì bạn có thể sử dụng 'std :: atomic '. _Edit: _ hoặc đúng hơn là std :: atomic_bool, xem như thế nào họ đã đi đến những rắc rối của một chuyên cho bạn! – Rook

+5

Bạn không thể biết trạng thái hiện tại, trừ khi bạn sử dụng đúng ngữ nghĩa thu được/giải phóng (tức là cố gắng khóa nó bằng 'atomic_flag_set', và sau đó chỉ thực hiện công việc nếu bạn thực sự thay đổi giá trị). Đơn giản chỉ cần đọc nó sẽ chỉ cho bạn biết giá trị là gì khi bạn đọc nó, và nó có thể đã thay đổi ngay lập tức sau đó. –

+0

@Mike: điều đó có thực sự quan trọng không? Âm thanh như tất cả các OP muốn là khả năng để thực hiện một đọc nguyên tử và có một số khái niệm về lần đọc và viết ra lệnh. – Rook

Trả lời

39

Bạn không thể đọc giá trị std::atomic_flag mà không đặt giá trị true. Điều này là do thiết kế. Nó không phải là một biến boolean (chúng tôi có std::atomic<bool> cho điều đó), nhưng một lá cờ tối thiểu được đảm bảo khóa miễn phí trên tất cả các kiến ​​trúc có hỗ trợ C++ 11.

Trên một số nền tảng, chỉ các hướng dẫn nguyên tử duy nhất là hướng dẫn trao đổi. Trên các nền tảng như vậy, std::atomic_flag::test_and_set() có thể được triển khai với exchange var,1clear() với exchange var,0, nhưng không có hướng dẫn nguyên tử nào để đọc giá trị.

Vì vậy, nếu bạn muốn đọc giá trị mà không thay đổi giá trị, thì bạn cần std::atomic<bool>.

+0

chỉ muốn trích dẫn cuốn sách của bạn .... – haohaolee

+0

Điều gì sẽ xảy ra nếu tôi chỉ muốn in giá trị của nó cho mục đích gỡ lỗi, vì vậy tôi không thực sự quan tâm rằng * điều này * đọc cụ thể là nguyên tử? Bây giờ tôi sử dụng phần tử '.__ val' cho điều đó, nhưng nó đưa ra lỗi trong một số phiên bản của gcc (đúng như vậy tôi đoán) – user1273684

+0

Bạn không thể đọc một cách hợp pháp giá trị của' std :: atomic_flag' cho bất kỳ mục đích nào mà không sửa đổi nó. Nếu bạn muốn đọc nó (ngay cả khi gỡ lỗi printf), bạn cần 'std :: atomic ' –

12

Nếu bạn muốn sử dụng atomic_flag để xác định xem một sợi nên thoát ra, bạn có thể làm điều đó như thế này:

khởi:

std::atomic_flag keep_running = ATOMIC_FLAG_INIT; 
keep_running.test_and_set(); 

Chủ đề vòng lặp:

while (keep_running.test_and_set()) { 
    // do thread stuff 
} 

Khi bạn muốn chuỗi để thoát:

keep_running.clear(); 
Các vấn đề liên quan