2012-03-17 47 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