C++11:并发、多线程

来源:互联网 发布:2017广联达软件多少钱 编辑:程序博客网 时间:2024/06/11 14:29

  • 原子操作和原子类型

原子操作和原子类型

通常情况下,原子操作是通过互斥(mutual exclusive)的访问来保证的。
Linux下借助POSIX标准的pthread库的互斥锁:

#include <iostream>#include <pthread.h>using namespace std;static long long total = 0;pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;void* func(void *){    for (long long i = 0; i < 100000000LL; ++i)    {        pthread_mutex_lock(&m);        total += i;        pthread_mutex_unlock(&m);    }}int main(){    pthread_t t1;    pthread_t t2;    if (pthread_create(&t1, NULL, &func, NULL))    {        throw;    }    if (pthread_create(&t2, NULL, &func, NULL))    {        throw;    }    pthread_join(t1, NULL);    pthread_join(t2, NULL);    cout << total << endl;  // 9999999900000000    return 0;}

上面代码为共享变量创建互斥锁(m),并在进入临界区前后进行加锁(pthread_mutex_lock)和解锁(pthread_mutex_unlock),从而保证累加的代码为原子操作。但这样对互斥锁的管理无疑是种负担,而在C++11中不需要如此麻烦:

#include <iostream>#include <atomic>#include <thread>using namespace std;atomic_llong total {0};     // 原子数据类型void func(int x){    cout << x << endl;    for (long long i = 0; i < 100000000LL; ++i)    {        total += i;    }}int main(){    thread t1(func, 0);    thread t2(func, 3);    t1.join();    t2.join();    cout << total << endl;  // 9999999900000000    return 0;}

原子数据类型在线程间被互斥地访问。相比pthread的实现,同步的是数据而不是代码,遵从了面向对象的思想。

这里写图片描述
除了使用上图中的已经定义好的原子类型,我们还可以使用atomic类模板,通过std::atomic<T> t;能定义出任意的原子类型。编译器会保证产生并发情况下行为良好的代码,以避免线程间对数据t的竞争。

0 0