Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::atomic_thread_fence

      From cppreference.com
      <cpp‎ |atomic
       
       
      Concurrency support library
      Threads
      (C++11)
      (C++20)
      this_thread namespace
      (C++11)
      (C++11)
      (C++11)
      Cooperative cancellation
      Mutual exclusion
      Generic lock management
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      Condition variables
      (C++11)
      Semaphores
      Latches and Barriers
      (C++20)
      (C++20)
      Futures
      (C++11)
      (C++11)
      (C++11)
      Safe reclamation
      Hazard pointers
      Atomic types
      (C++11)
      (C++20)
      Initialization of atomic types
      (C++11)(deprecated in C++20)
      (C++11)(deprecated in C++20)
      Memory ordering
      (C++11)(deprecated in C++26)
      atomic_thread_fence
      (C++11)
      Free functions for atomic operations
      Free functions for atomic flags
       
      Defined in header<atomic>
      extern"C"void atomic_thread_fence(std::memory_order order)noexcept;
      (since C++11)

      Establishesmemory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed byorder, without an associated atomic operation. Note however, that at least one atomic operation is required to set up the synchronization, as described below.

      Contents

      [edit]Fence-atomic synchronization

      A release fenceF in threadA synchronizes-with atomicacquire operationY in threadB, if

      • there exists an atomic storeX (with any memory order),
      • Y reads the value written byX (or the value would be written byrelease sequence headed byX ifX were a release operation),
      • F is sequenced-beforeX in threadA.

      In this case, all non-atomic and relaxed atomic stores that aresequenced-beforeF in threadA willhappen-before all non-atomic and relaxed atomic loads from the same locations made in threadB afterY.

      [edit]Atomic-fence synchronization

      An atomicrelease operationX in threadA synchronizes-with an acquire fenceF in threadB, if

      • there exists an atomic readY (with any memory order),
      • Y reads the value written byX (or by therelease sequence headed by X),
      • Y is sequenced-beforeF in threadB.

      In this case, all non-atomic and relaxed atomic stores that aresequenced-beforeX in threadA willhappen-before all non-atomic and relaxed atomic loads from the same locations made in threadB afterF.

      [edit]Fence-fence synchronization

      A release fenceFA in threadA synchronizes-with an acquire fenceFB in threadB, if

      • there exists an atomic objectM,
      • there exists an atomic writeX (with any memory order) that modifiesM in threadA,
      • FA is sequenced-beforeX in threadA,
      • there exists an atomic readY (with any memory order) in threadB,
      • Y reads the value written byX (or the value would be written byrelease sequence headed byX ifX were a release operation),
      • Y is sequenced-beforeFB in threadB.

      In this case, all non-atomic and relaxed atomic stores that aresequenced-beforeFA in threadA willhappen-before all non-atomic and relaxed atomic loads from the same locations made in threadB afterFB.

      Depending on the value of theorder parameter, the effects of this call are:

      [edit]Parameters

      order - the memory ordering executed by this fence

      [edit]Notes

      On x86 (including x86-64),atomic_thread_fence functions issue no CPU instructions and only affect compile-time code motion, except forstd::atomic_thread_fence(std::memory_order_seq_cst).

      atomic_thread_fence imposes stronger synchronization constraints than an atomic store operation with the samestd::memory_order. While an atomic store-release operation prevents all preceding reads and writes from moving past the store-release, anatomic_thread_fence withstd::memory_order_release ordering prevents all preceding reads and writes from moving past all subsequent stores.

      Fence-fence synchronization can be used to add synchronization to a sequence of several relaxed atomic operations, for example:

      // Globalstd::string computation(int);void print(std::string); std::atomic<int> arr[3]={-1,-1,-1};std::string data[1000];//non-atomic data // Thread A, compute 3 values.void ThreadA(int v0,int v1,int v2){//  assert(0 <= v0, v1, v2 < 1000);    data[v0]= computation(v0);    data[v1]= computation(v1);    data[v2]= computation(v2);    std::atomic_thread_fence(std::memory_order_release);std::atomic_store_explicit(&arr[0], v0,std::memory_order_relaxed);std::atomic_store_explicit(&arr[1], v1,std::memory_order_relaxed);std::atomic_store_explicit(&arr[2], v2,std::memory_order_relaxed);} // Thread B, prints between 0 and 3 values already computed.void ThreadB(){int v0=std::atomic_load_explicit(&arr[0],std::memory_order_relaxed);int v1=std::atomic_load_explicit(&arr[1],std::memory_order_relaxed);int v2=std::atomic_load_explicit(&arr[2],std::memory_order_relaxed);    std::atomic_thread_fence(std::memory_order_acquire);//  v0, v1, v2 might turn out to be -1, some or all of them.//  Otherwise it is safe to read the non-atomic data because of the fences:if(v0!=-1)        print(data[v0]);if(v1!=-1)        print(data[v1]);if(v2!=-1)        print(data[v2]);}

      [edit]Example

      Scan an array of mailboxes, and process only the ones intended for us, without unnecessary synchronization.This example uses atomic-fence synchronization.

      constint num_mailboxes=32;std::atomic<int> mailbox_receiver[num_mailboxes];std::string mailbox_data[num_mailboxes]; // The writer threads update non-atomic shared data// and then update mailbox_receiver[i] as follows:mailbox_data[i]= ...;std::atomic_store_explicit(&mailbox_receiver[i], receiver_id,std::memory_order_release); // Reader thread needs to check all mailbox[i], but only needs to sync with one.for(int i=0; i< num_mailboxes;++i)if(std::atomic_load_explicit(&mailbox_receiver[i],std::memory_order_relaxed)== my_id){// synchronize with just one writer        std::atomic_thread_fence(std::memory_order_acquire);// guaranteed to observe everything done in the writer thread// before the atomic_store_explicit()        do_work(mailbox_data[i]);}

      [edit]See also

      defines memory ordering constraints for the given atomic operation
      (enum)[edit]
      fence between a thread and a signal handler executed in the same thread
      (function)[edit]
      C documentation foratomic_thread_fence
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/atomic/atomic_thread_fence&oldid=183355"

      [8]ページ先頭

      ©2009-2026 Movatter.jp