Порядки памяти используются для определения порядка памяти в элементарных операциях. Простейший порядок памяти - memory_order_seq_cst
, что обеспечивает последовательную последовательность. Другие модели памяти дают спокойное упорядочение памяти.
Если вы хотите получить приобретаемый релиз , вы должны объединить: memory_order_consume
, memory_order_acquire
, memory_order_release
и
memory_order_acq_rel
.
Если вы хотите получить расслабленный заказ, вы должны использовать memory_order_relaxed
.
Вот простой пример использования упорядочения памяти для реализации мьютекса спин-блокировки:
class spinlock_mutex {
private:
std::atomic_flag f;
public:
spinlock_mutex() : f(ATOMIC_FLAG_INIT) {}
void lock() {
while (f.test_and_set(std::memory_order_acquire)) {}
}
void unlock() {
flag.clear(std::memory_order_release());
}
};
В C ++ 11 есть тип data_cond. Я полагаю, что вы можете ссылаться на std::condition_variable
, который является условной переменной, которая должна быть связана с мьютексом.
std::mutex m;
std::queue<request> q;
std::condition_variable cv;
void producer() {
while (more_data()) {
request r = generate_request();
std::lock_guard<std::mutex> l(m);
q.push(r);
cv.notify_one();
}
}
void consumer() {
for (;;) {
std::unique_lock<std::mutex> l(m);
cv.wait(l, []{ return !q.empty();});
request r = q.front();
l.unlock();
process_request(r);
if (is_last(r)) break;
}
}
Наконец, будущее позволяет потоку возвращать значение в раздел кода, который сделал вызов.
int main() {
std::future<int> r = std::async(do_something, 1, 10);
do_something_else();
std::cout << “Result= “ << r.get() << std::endl;
return 0;
}