std::atomic_fetch_and, std::atomic_fetch_and_explicit
提供: cppreference.com
ヘッダ <atomic> で定義 | ||
(1) | (C++11以上) | |
template<class T > T atomic_fetch_and(std::atomic<T>* obj, | ||
template<class T > T atomic_fetch_and(volatilestd::atomic<T>* obj, | ||
(2) | (C++11以上) | |
template<class T > T atomic_fetch_and_explicit(std::atomic<T>* obj, | ||
template<class T > T atomic_fetch_and_explicit(volatilestd::atomic<T>* obj, | ||
obj
の古い値と arg
の間でビット単位の論理積を取った結果で obj
の指す値をアトミックに置き換えます。 obj
がそれまで保持していた値を返します。
この操作は以下のコードが実行されたかのように行われます。
1)obj->fetch_and(arg)
2)obj->fetch_and(arg, order)
std::atomic<T>
に fetch_and
メンバがない場合 (このメンバは整数型に対してのみ提供されます)、プログラムは ill-formed です。
目次 |
[編集]引数
obj | - | 変更するアトミックオブジェクトを指すポインタ。 bool はアトミック操作の目的に対しては整数型とみなされません。 |
arg | - | アトミックオブジェクトに格納されている値とビット単位の論理積を取る値 |
order | - | この操作に対するメモリ同期順序付け。 すべての値を指定できます。 |
[編集]戻り値
*obj
の変更順序における、この関数の効果の直前の値。
[編集]実装例
template<class T > T atomic_fetch_and(std::atomic<T>* obj, typenamestd::atomic<T>::value_type arg )noexcept{return obj->fetch_and(arg);} |
[編集]例
Run this code
#include <iostream>#include <atomic>#include <thread>#include <chrono>#include <functional> // Binary semaphore for demonstrative purposes only// This is a simple yet meaningful example: atomic operations// are unnecessary without threads. class Semaphore { std::atomic_char m_signaled;public: Semaphore(bool initial =false){ m_signaled = initial;}// Block until semaphore is signaledvoid 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 {staticconstint N =100;staticconstint 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();// signal printing to occur m_count_sem.take();// wait until printing is complete proceeding}}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 | exact type match required because T is deduced from multiple arguments | T is deduced from the atomic argument only |
[編集]関連項目
アトミックオブジェクトの値と引数の値のビット単位の論理積をアトミックに行い、以前保持されていた値を取得します ( std::atomic<T> のパブリックメンバ関数) | |
(C++11)(C++11) | アトミックオブジェクトの値を非アトミック引数とビット単位の論理和を取った結果で置き換え、アトミックの以前の値を取得します (関数テンプレート) |
(C++11)(C++11) | アトミックオブジェクトの値を非アトミック引数とビット単位の排他的論理和を取った結果で置き換え、アトミックの以前の値を取得します (関数テンプレート) |
atomic_fetch_and, atomic_fetch_and_explicit の C言語リファレンス |