#include "pch.h"
#include <iostream>
#include <thread>
#include <list>
#include <mutex>
#include <future>
#include <mutex>
using namespace std;
int mythread() //线程入口函数
{
cout << "mythread() start" << "thread id =" << this_thread::get_id() << endl; //打印线程id
chrono::milliseconds dura(3000);
this_thread::sleep_for(dura); //休息3s
cout << "mythread() end" << "thread id =" << this_thread::get_id() << endl; //打印线程id
return 5;
}
//int g_mycount = 0; //全局变量
atomic <int> g_mycount; //将全局变量修改为类型为int的atomic对象,则可以像操作int类型变量一样来操作这个对象
mutex my_mutex;
void count_thread()
{
for (int i = 0; i < 10000000; i++)
{
/*
//全局变量配合互斥量
my_mutex.lock(); //加锁后,计算的值稳定,但消耗接近5秒
g_mycount++;
my_mutex.unlock();
*/
g_mycount++; //修改为atomic对象,对应的操作是原子操作,不会被打断,且效率更高(接近2秒)
}
}
int main()
{
//一:future的其他函数
//int tempvar = 12;
//cout << "main " << "thread id =" << this_thread::get_id() << endl;
//future <int> result = async(launch::deferred,mythread); //自动创建一个线程并开始执行对应的线程入口函数,返回一个future对象。流程不会卡在这里
//cout << "continue.....!" << endl;
// cout << result.get() << endl; //卡在这里等待mythread()执行完毕,拿到结果。只能调用一次,调用多次会报异常
//wait_for:等待一定的时间
//枚举类型
//future_status status = result.wait_for(chrono::seconds(6)); //等待一秒
//if (status == future_status::timeout) //等待一秒,希望返回
//{
// //超时:表示线程还没执行完
// cout << "超时,线程还未执行完" << endl;
//}
//else if (status == future_status::ready)
//{
// //表示线程成功返回
// cout << "线程成功执行完毕,返回" << endl;
// cout << result.get() << endl;
//}
//else if (status == future_status::deferred)
//{
// //如果async的第一个参数被设置为launch::deferred,则本条件成立
// cout << "线程被延迟执行" << endl;
// cout << result.get() << endl;
//}
//cout << "主线程end" << endl;
//二:std::shared_future:也是个类模板,get()函数是复制数据,可以多次调用get。
//三:原子操作:atomic
//(3.1)原子操作概念引出范例
//互斥量:多线程编程中,保护共享数据,可以针对一行或多行代码(代码段)。 上锁->操作共享数据->开锁
//有两个线程,对一个变量进行操作,一个线程读,一个变量写
//可以把原子操作理解为: 不需要用到互斥量加锁(无锁)技术的多线程并发编程方式。在多线程中不会被打断的程序执行片段。
//原子操作效率比互斥量更好,但一般针对一个变量,而不是一个代码段
//原子操作一般指“不可分割的操作”。这种操作状态要么是完成的,要么是未开始的。不存在半完成的状态
//std::atomic来代表原子操作,是一个类模板,用来封装某个类型的值
thread t1(count_thread);
thread t2(count_thread);
t1.join();
t2.join();
cout << g_mycount << endl; //如果不加锁,最后的结果不一定是2000万(不稳定)
//四:总结
//一般用于计数或者统计(累计发送出去多少个数据包,累计接收到了多少个数据包)
return 0;
}
#include "pch.h"
#include <iostream>
#include <thread>
#include <list>
#include <mutex>
#include <future>
#include <mutex>
using namespace std;
atomic <int> g_mycount = 0; //将全局变量修改为类型为int的atomic对象,则可以像操作int类型变量一样来操作这个对象
void count_thread()
{
for (int i = 0; i < 10000000; i++)
{
g_mycount++;
g_mycount += 1;
//g_mycount = g_mycount + 1; //运行结果不稳定
}
}
int mythread()
{
cout << "my thread start, thread id =" << this_thread::get_id() << endl;
return 1;
}
int main()
{
//一:原子操作atomic续谈
//一般原子操作,针对++,--,+=,-=,&=,|=,^= 等运算符是支持的,其他的可能不支持。
/*thread t1(count_thread);
thread t2(count_thread);
t1.join();
t2.join();
cout << g_mycount << endl;*/
//二:async深入谈
//(2.1)async参数详谈。async用来创建一个异步任务;
cout << "main thread start, thread id =" << this_thread::get_id() << endl;
future<int> result = async(mythread);
cout << result.get() << endl;
//async()一般不叫创建线程(即使有时候它能够创建线程),一般叫它创建一个异步任务
//thread(),如果系统资源紧张,那么创建线程就会失败,那么执行thread()时整个程序可能崩溃。
//async与thread最明显的不同,就是async有时候并不创建新线程
//a)如果用launch::deferred来调用async() :async(launch::deferred,mythread); 延迟调用,并不会创建线程,延迟到主线程调用wait和get时才会执行,否则不会执行。
//b)async(launch::async,mythread):强制异步任务在新线程上执行(会创建新线程)
//c)async(launch::async | launch::deferred,mythread):两种都有可能,由系统决定
//d)async(mythread):不带参数时,效果同async(launch::async | launch::deferred,mythread),由系统自行决定调用方式(同步:不创建新线程还是异步:创建新线程)
//(2.2)async()与thread()的区别
//thread(),如果系统资源紧张,那么创建线程就会失败,那么执行thread()时整个程序可能崩溃
//获取thread()入口函数返回值需要通过全局变量等手段来获取
//async创建异步任务,可能创建线程也可能不创建线程,并且容易拿到线程入口函数的返回值
//系统资源限制时:如果用thread()创建线程太多,则可能创建失败,系统报告异常,崩溃;
// 如果用async,launch::async | launch::deferred或不带参数时,一般就不会报异常不会崩溃(在此情况下不创建新线程,会运行在调用get或wait的线程上)
//一个程序里,线程数量不宜超过100 ~ 200
//(2.3)不确定性问题的解决
//不带参数时,由系统自行决定调用方式,则存在不确定性
//解决不确定性:
future <int> result = async(mythread);
//future_status status = result.wait_for(chrono::seconds(0)); //等0秒
future_status status = result.wait_for(0s); //同样也是等0秒
if (status == future_status::deferred)
{
//线程被延迟执行了(系统资源紧张,采用launch::deferred策略了)
cout << result.get() << endl; //这个时候才去调用了mythread()
}
else
{
//任务没有被推迟,已经开始运行了,线程被创建了
if (status == future_status::ready)
{
cout << result.get() << endl;
}
else if (status == future_status::timeout)
{
cout << "线程超时,没执行完" << endl;
}
}
return 0;
}