头文件
#include<atomic>
using namespace std;
template<class T> struct atomic;
atomic<T>模板类,生成一个T类型的原子对象,并提供了系列原子操作函数。
atomic_flag类
atomic_flag 一种简单的原子布尔类型,只支持两种操作,test_and_set和 clear.
(1)如果某个std::atomic_flag对象使用ATOMIC_FLAG_INIT宏初始化,那么可以保证该对象创建时处于clear状态。
(2)test_and_set()函数检查std::atomic_flag标志。
(3)如果atomic_flag之前没有被设置过,则设置atomic_flag的标志,并返回先前该atomic_flag对象是否被设置过,被设置返回true,否则false.
/*
原子操作。atomic
它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。
也就是他确保了在同一时刻只有唯一的线程对这个资源进行访问。
这有点类似互斥对象对共享资源的访问的保护,但是原子操作更加接近底层,因而效率更高。
*/
#include<thread>
#include<atomic> //原子操作头文件
#include<iostream>
using namespace std;
atomic<int> N = 0; //用atomic保证对N的操作原子性
//int N = 0;
void ThreadFun(void);
int main()
{
thread t1(ThreadFun);
thread t2(ThreadFun);
t1.join();
t2.join();
cout << N << endl;
system("pause");
return 0;
}
void ThreadFun(void)
{
for (int i = 0; i < 100000; i++)
{
N++; //线程并发导致 加操作 重叠,不是原子操作,因此可能少于200000.
}
}
//模拟十人赛跑
#include<iostream>
#include<thread>
#include<atomic>
#include<vector>
using namespace std;
using namespace std::this_thread;
atomic<bool> ready = false; //是否开始
atomic_flag win = ATOMIC_FLAG_INIT; //终点线
void RunThread(int id);
int main()
{
vector<thread> run;
for (int i = 1; i <= 10; i++)
{
run.push_back(thread(RunThread, i));
}
//准备发命令预备跑
cout << "十队参加比赛,已准备!" << endl;
sleep_for(chrono::seconds(1));
cout << "3!" << endl;
sleep_for(chrono::seconds(1));
cout << "2!" << endl;
sleep_for(chrono::seconds(1));
cout << "1! 开始" << endl;
ready = true; //开始
//等待所有人跑完
for (thread &t : run)
{
t.join();
}
system("pause");
return 0;
}
void RunThread(int id)
{
while (!ready) yield(); //判断是否开始,未开始让其他线程先执行
for (int i = 0; i < 100000; i++) {} //跑的过程
if (!win.test_and_set()) //如果没有被设置过,返回false ,调用后会设置
cout << id << "号队伍获得冠军" << endl;
}
以上为学习笔记。