std:: atomic_fetch_and, std:: atomic_fetch_and_explicit
|
ヘッダで定義
<atomic>
|
||
|
template
<
class
T
>
T atomic_fetch_and
(
std::
atomic
<
T
>
*
obj,
|
(1) | (C++11以降) |
|
template
<
class
T
>
T atomic_fetch_and
(
volatile
std::
atomic
<
T
>
*
obj,
|
(2) | (C++11以降) |
|
template
<
class
T
>
T atomic_fetch_and_explicit
(
std::
atomic
<
T
>
*
obj,
|
(3) | (C++11以降) |
|
template
<
class
T
>
T atomic_fetch_and_explicit
(
volatile
std::
atomic
<
T
>
*
obj,
|
(4) | (C++11以降) |
obj が指す値を、 obj の旧値と arg のビット単位AND演算の結果で原子的に置き換えます。 obj が以前保持していた値を返します。
この操作は、以下のコードが実行されるかのように行われます:
std::atomic<T>
に
fetch_and
メンバが存在しない場合(このメンバは
整数型
に対してのみ提供され、
bool
を除く)、プログラムは不適格となります。
目次 |
パラメータ
| obj | - | 変更対象のアトミックオブジェクトへのポインタ |
| arg | - | アトミックオブジェクトに格納された値とビット単位AND演算する値 |
| order | - | メモリ同期順序 |
戻り値
この関数の効果が適用される直前の値、 変更順序 における * obj の値。
例
#include <atomic> #include <chrono> #include <functional> #include <iostream> #include <thread> // デモンストレーション目的のみのバイナリセマフォ // これはシンプルでありながら意味のある例です:アトミック操作は // スレッドなしでは不要です class Semaphore { std::atomic_char m_signaled; public: Semaphore(bool initial = false) { m_signaled = initial; } // セマフォがシグナルされるまでブロック void take() { while (!std::atomic_fetch_and(&m_signaled, false)) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void put() { std::atomic_fetch_or(&m_signaled, true); } }; class ThreadedCounter { static const int N = 100; static const int REPORT_INTERVAL = 10; int m_count; bool m_done; Semaphore m_count_sem; Semaphore m_print_sem; void count_up() { for (m_count = 1; m_count <= N; ++m_count) if (m_count % REPORT_INTERVAL == 0) { if (m_count == N) m_done = true; m_print_sem.put(); // 印刷が行われるようにシグナル m_count_sem.take(); // 印刷が完了するまで待機してから進行 } std::cout << "count_up() done\n"; m_done = true; m_print_sem.put(); } void print_count() { do { m_print_sem.take(); std::cout << m_count << '\n'; m_count_sem.put(); } while (!m_done); std::cout << "print_count() done\n"; } public: ThreadedCounter() : m_done(false) {} void run() { auto print_thread = std::thread(&ThreadedCounter::print_count, this); auto count_thread = std::thread(&ThreadedCounter::count_up, this); print_thread.join(); count_thread.join(); } }; int main() { ThreadedCounter m_counter; m_counter.run(); }
出力:
10 20 30 40 50 60 70 80 90 100 print_count() done count_up() done
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| P0558R1 | C++11 |
正確な型の一致が要求されていた。これは
T
が複数の引数から推論されていたため
|
T
は obj からのみ
推論される |
関連項目
|
引数とアトミックオブジェクトの値との間でビット単位のANDをアトミックに実行し、以前に保持されていた値を取得する
(
std::atomic<T>
の公開メンバ関数)
|
|
|
(C++11)
(C++11)
|
非アトミック引数とのビット単位のORの結果でアトミックオブジェクトを置き換え、アトミックオブジェクトの以前の値を取得する
(関数テンプレート) |
|
(C++11)
(C++11)
|
非アトミック引数とのビット単位のXORの結果でアトミックオブジェクトを置き換え、アトミックオブジェクトの以前の値を取得する
(関数テンプレート) |
|
Cドキュメント
for
atomic_fetch_and
,
atomic_fetch_and_explicit
|
|