2012-03-17 49 views
6

我有一組的C++函數:原子操作在C++

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

現在我要讓funcA原子,即內部funcAfuncBfuncC呼叫應當被自動執行。有什麼辦法可以做到這一點?

+1

你能否解釋一下你所說的「執行原子」是什麼意思?聽起來你只是想要一個'std :: mutex'。 – Potatoswatter 2012-03-18 00:37:35

+1

這可能是他真正想要的。 – Joshua 2012-03-18 01:39:59

+1

也許有人應該給他看適當的語法來使用'std :: mutex'。也許他不知道。我不知道如何在其他一些語言中使用互斥鎖。解釋應該包括假設整個程序必須尊重互斥體。即線程B仍然可以調用funcB和funcC,即使線程A在互斥量下執行,除非程序員通過設計禁止它。 – 2012-03-18 02:37:31

回答

6

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

+0

請注意,雖然這個答案嚴格來說是正確的,Robᵩ的回答對user744829更有用。 – Joshua 2012-03-18 19:40:35

11

您可以完成此操作的一種方法是使用新的(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的類的類成員。
1

如果你正在使用gcc 4.7比你可以使用新的事務內存功能來做到以下幾點:

事務內存的目的是使編程與線程簡單,尤其是同步訪問共享數據在幾個線程之間使用事務。與數據庫一樣,交易是一個工作單元,它要麼全部完成,要麼完全沒有效果(即交易以原子方式執行)。此外,交易彼此隔離,以便每筆交易都能看到一致的內存視圖。

目前,事務僅以C++和C以事務語句,事務表達式和函數事務的形式支持。在以下示例中,a和b將被讀取和差將被寫入到c,所有原子和孤立的其他事務:

__transaction_atomic { c = a - b; } 

因此,另一個線程可以使用以下代碼來同時更新B,不含不曾導致C到保持負值(和,而無需使用其他同步結構如鎖或C++ 11原子公司):在的C++ 11術語定義記錄,

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

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

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