首页 > 编程语言 >C++中的原子操作

C++中的原子操作

时间:2024-04-23 16:46:32浏览次数:22  
标签:int gConter C++ 原子 ++ atomic POLICY 操作

一、概述

C++11提供了一个原子类型 std::atomic<T>, 通过这个原子类型管理的内部变量就可以称之为原子变量,我们可以给原子类型指定 bool、char、int、long、指针 等类型作为模板参数(不支持浮点类型和复合类型)。

原子指的是一系列不可被CPU上下文交换的机器指令,这些指令组合在一起就形成了原子操作。在多核CPU下,当某个CPU核心开始运行原子操作时,会先暂停其它CPU内核对内存的操作,以保证原子操作不会被其它CPU内核所干扰。

由于原子操作是通过指令提供的支持,因此它的性能相比锁和消息传递会好很多。相比较于锁而言,原子类型不需要开发者处理加锁和释放锁的问题,同时支持修改,读取等操作,还具备较高的并发性能,几乎所有的语言都支持原子类型。

 

二、实验

1. 原子变量计数与耗时实验

(1) counter_test.cpp

#include <thread>
#include <atomic>
#include<mutex>
#include <iostream>

using namespace std;

#define POLICY_ATOMIC //POLICY_MUTEX POLICY_ATOMIC POLICY_NO

const int maxCnt = 1000000;

#ifdef POLICY_NO
int gConter = 0;
void mythread()
{
    for (int i = 0; i < maxCnt; i++) {
        gConter++;  //线程同时操作变量
    }
}
#endif

#ifdef POLICY_MUTEX
int gConter = 0;
mutex mut;
void mythread()
{
    for (int i = 0; i < maxCnt; i++) {
        mut.lock();    //加锁操作
        gConter++;
        mut.unlock();
    }
}
#endif

#ifdef POLICY_ATOMIC
atomic<int> gConter;
void mythread()
{
    for (int j = 0; j < maxCnt; j++) {
        gConter++;
    }
}
#endif

int main()
{
    auto begin = chrono::high_resolution_clock::now();
    thread t1(mythread);
    thread t2(mythread);
    t1.join();
    t2.join();
    auto end = chrono::high_resolution_clock::now();
    cout << "gConter=" << gConter << endl;
    cout << "time: " << chrono::duration_cast<chrono::microseconds>(end - begin).count() * 1e-6 << "s" << endl; //秒计时
}

 

(2) 结果

~/tmp/3.cpp_test/2.atomic$ g++ -std=c++11 counter_test.cpp -lpthread -o pp

~/tmp/3.cpp_test/2.atomic$ ./pp
gConter=1487831
time: 0.0155s

~/tmp/3.cpp_test/2.atomic$ ./pp 使用muetx
gConter=2000000
time: 0.192604s

~/tmp/3.cpp_test/2.atomic$ ./pp 原子操作的
gConter=2000000
time: 0.052044s

 

标签:int,gConter,C++,原子,++,atomic,POLICY,操作
From: https://www.cnblogs.com/hellokitty2/p/18153188

相关文章

  • k8s 操作命令-合集List
    k8s操作命令合集List ---------------k8s基本常用的命令-----------------------------------------1、创建资源kubectlcreatedeploymentnginx--image=nginx2、列出资源kubectlgetpods3、描述资源kubectldescribepod<pod-name>4、删除资源......
  • 3568F-麒麟KylinOS国产操作系统演示案例
     ......
  • 3568F-翼辉SylixOS国产操作系统演示案例
     ......
  • 无root权限,解决conda环境的报错ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6:
    网上的方法都需要sudo或者root权限,但是服务器多是实验室公用,没有ruuto权限,因此更好的办法是通过conda只改自己虚拟环境的环境变量。问题原因问题的根本原因是Linux系统没有GLIBCXX_3.4.30动态链接库。这个库和gcc版本有关。因此要么你更换版本,要么找一个别的so链接到这个连接......
  • 在Linux中,什么是管道操作,以及如何使用它?
    在Linux中,管道操作是一种强大而灵活的机制,用于在多个命令或者进程之间传输数据。它允许一个命令的输出直接作为另一个命令的输入,从而实现数据的连续处理,无需通过中间文件来存储数据。管道的核心思想是提高命令行操作的效率和简洁性。1.管道操作的概念管道实质上是一个进程间通......
  • 【Redis】Redis的操作命令(二)——Redis 字符串(String)
    常见的Redis字符串命令如下:命令说明例子SETkeyvalue设置指定key的值 GETkey获取指定key的值 GETRANGEkeystartend返回key中字符串值的子字符 GETRANGEmykey03 GETSETkeyvalue将给定key的值设为value,并返回key的旧值(oldvalu......
  • 使用FAL操作STM32F103VET6单片机的片内flash和外部norflash(SFUD驱动)
    1.新建一个命名为fal的工程,控制台串口我使用了uart5,对应管脚PC12和PD2工程新建好以后,编译,报错双击改报错信息,跳转到下图这个位置 把RT_WEAK改为rt_weak,后重新编译,下载到单片机中重新正常运行2.双击CubeMXSettings,选择正确的单片机型号,配置norflash使用的SPI......
  • C语言单向链表的增删操作
    //指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改typedefintDataType_t;//构造链表的结点,链表中所有结点的数据类型应该是相同的typedefstructLinkedList{  DataType_tdata;    //结点的数据域  structLinkedList*next;......
  • Java泛型如何对属性操作
    对于多个类型相似的操作,如何实现统一处理,简化操作。例如,现在由多个类定义,类定义中都包含客户编号,但是缺少客户名称。如果采用常规的方式,我对于需要展示客户名称的场景,需要对每个类的每个场景去处理,来根据客户编号获取客户信息,并设置客户名称。但是这种方式对存在很多的冗余代码......
  • C++ Standard Library
    C++StandardLibraryarchitecure&sourcesc++官网C标准库->一个一个单一的函数function->彼此几乎无关联c++标准库->六个部分->彼此之间有紧密的关联c++标准库主要是用模板做出来的泛型编程(GenericProgramming)使用模板作为主要工具来编写程序->templates模......