簡體   English   中英

C ++中的原子操作

[英]Atomic Operations in C++

我有一組C ++函數:

funcB(){};
funcC(){};
funcA()
{
    funcB();
    funcC();
}

現在,我想使funcA原子,即funcBfuncC調用內部funcA ,應自動執行。 有沒有辦法實現這個目標?

一種方法是使用新的(C ++ 11)功能std::mutexstd::lock_guard

對於每個受保護資源,您實例化一個全局std::mutex ; 然后每個線程通過創建std::lock_guard鎖定該互斥鎖(如需要):

#include <thread>
#include <iostream>
#include <mutex>
#include <vector>

// A single mutex, shared by all threads. It is initialized
// into the "unlocked" state
std::mutex m;

void funcB() {
  std::cout << "Hello ";
}
void funcC() {
  std::cout << "World." << std::endl;
}
void funcA(int i) {

  // The creation of lock_guard locks the mutex
  // for the lifetime of the lock_guard
  std::lock_guard<std::mutex> l(m);

  // Now only a single thread can run this code
  std::cout << i << ": ";
  funcB();
  funcC();

  // As we exit this scope, the lock_guard is destroyed, 
  // the mutex is unlocked, and another thread is allowed to run
}

int main () {
  std::vector<std::thread> vt;

  // Create and launch a bunch of threads
  for(int i =0; i < 10; i++)
    vt.push_back(std::thread(funcA, i));

  // Wait for all of them to complete
  for(auto& t : vt)
    t.join();
}

筆記:

  • 在您的示例中,與funcA無關的某些代碼可以調用funcBfuncC而無需遵守funcA設置的鎖定。
  • 根據程序的結構,您可能希望以不同方式管理互斥鎖的生命周期。 例如,它可能希望成為包含funcA的類的類成員。

一般來說,NO。 非常精確地定義了原子操作。 你想要的是信號量或互斥量。

如果您使用GCC 4.7,則可以使用新的Transactional Memory功能執行以下操作:

事務性內存旨在使線程編程更簡單,特別是使用事務同步訪問多個線程之間共享的數據。 與數據庫一樣,事務是一個工作單元,可以完全完成或根本不起作用(即,事務以原子方式執行)。 此外,事務彼此隔離,使得每個事務看到一致的內存視圖。

目前,事務僅以事務語句,事務表達式和函數事務的形式在C ++和C中受支持。 在下面的示例中,將讀取a和b兩者,並且差異將寫入c,全部原子並與其他事務隔離:

__transaction_atomic { c = a - b; }

因此,另一個線程可以使用以下代碼同時更新b而不會導致c保持負值(並且不必使用其他同步構造,如鎖或C ++ 11原子):

__transaction_atomic { if (a > b) b++; }

事務的精確語義是根據C ++ 11 / C1X內存模型定義的(參見下面的規范鏈接)。 粗略地說,事務提供的同步保證類似於使用單個全局鎖作為所有事務的保護時所保證的保證。 請注意,與C / C ++中的其他同步構造一樣,事務依賴於無數據爭用的程序(例如,與對同一存儲器位置的事務讀取並發的非事務性寫入是數據爭用)。

更多信息: http//gcc.gnu.org/wiki/TransactionalMemory

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM