Các ngây thơ boolean phủLàm thế nào để phủ nhận nguyên tử một std :: atomic_bool?
std::atomic_bool b;
b = !b;
dường như không phải là nguyên tử. Tôi nghi ngờ điều này là bởi vì operator!
kích hoạt một diễn viên để đồng bằng bool
. Làm thế nào để thực hiện một cách nguyên tử sự phủ định tương đương? Các mã sau minh họa rằng sự phủ định ngây thơ không phải là nguyên tử:
#include <thread>
#include <vector>
#include <atomic>
#include <iostream>
typedef std::atomic_bool Bool;
void flipAHundredThousandTimes(Bool& foo) {
for (size_t i = 0; i < 100000; ++i) {
foo = !foo;
}
}
// Launch nThreads std::threads. Each thread calls flipAHundredThousandTimes
// on the same boolean
void launchThreads(Bool& foo, size_t nThreads) {
std::vector<std::thread> threads;
for (size_t i = 0; i < nThreads; ++i) {
threads.emplace_back(flipAHundredThousandTimes, std::ref(foo));
}
for (auto& thread : threads) thread.join();
}
int main() {
std::cout << std::boolalpha;
Bool foo{true};
// launch and join 10 threads, 20 times.
for (int i = 0; i < 20; ++i) {
launchThreads(foo, 10);
std::cout << "Result (should be true): " << foo << "\n";
}
}
Mã này ra mắt 10 chủ đề, mỗi trong số đó flips các atomic_bool một larrge, thậm chí, số lần (100000), và in ra boolean. Điều này được lặp lại 20 lần.
EDIT: Đối với những người muốn chạy mã này, tôi đang sử dụng ảnh chụp GCC 4.7 trên ubuntu 11.10 với hai lõi. Các tùy chọn biên dịch là:
-std=c++0x -Wall -pedantic-errors -pthread
Nhìn vào thông số kỹ thuật, các loại nguyên tử như 'std :: atomic_bool' và 'std :: nguyên tử' không có toán tử boolean như 'toán tử!'. Vì vậy, '! B' thực sự liên quan đến toán tử chuyển đổi (ẩn) của các kiểu nguyên tử. Tôi không làm câu trả lời này vì tôi không chắc chắn về cách cung cấp chức năng bạn cần. –
@LucDanton Quyền, và tôi không thể tìm thấy bất cứ điều gì về một nhà điều hành 'chuyên biệt! 'Cho nguyên tử, vì vậy tôi chắc chắn rằng sự chuyển đổi xảy ra, và nó rất có thể là nguyên nhân của cuộc đua. – juanchopanza
Đây là những gì tôi nhận được khi tôi chạy chương trình của bạn: 'chấm dứt được gọi sau khi ném một thể hiện của 'std :: system_error'' –