繁体   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