future其他成员函数、shared_future、atomic
一、future其他成员函数
线程的三种状态。1.ready 2.time_out 3.deferred
#include <iostream>
#include <future>
#include <vector>
using namespace std;
int mythread()
{
cout << "int mythread() start,thread id=" << std::this_thread::get_id() << endl;
chrono::milliseconds dura(5000);
this_thread::sleep_for(dura);
cout << "int mythread() end,thread id=" << std::this_thread::get_id() << endl;
return 5;
}
int main()
{
cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
//future<int> result = async(std::launch::deferred,mythread); //launch::deferred 不会创建子线程,是和主线程是一个线程
future<int> result = async(mythread);
cout << "continue...!" << endl;
//cout << result.get() << endl;
future_status status = result.wait_for(chrono::seconds(6));
if (status == future_status::timeout) //超时:表示线程还没执行完,希望1秒钟内就返回,但是没有返回,此时就会超时;
{
cout << "超时了,线程还没有执行完." << endl;
}
else if (status == future_status::ready)
{
cout << "表示线程成功返回了." << endl;
}
else if (status == future_status::deferred) // async 的第一个参数是std::launch::deferred 的话,这个条件就会成立。
{
cout << "async 的第一个参数是std::launch::deferred.,线程被延迟执行." << endl;
cout << result.get() << endl;
}
cout << "I Love China!" << endl;
return 0;
}
二、std::shared_future
future 类模板的get() 函数,不能多次调用get()的原因是,比如下面代码就是错的。
future<int> tmp;
auto result = tmp.get();
auto result2 = tmp.get(); //错误,只能get()一次,不能get()两次
因为get()函数的设计是一个移动语义,第一次调用get()后,tmp中的内容已经全部都被移动到result中去了。
shared_future 里面同样有get()函数,这个里面的设计就不是移动语义,而是赋值语义。
三、原子操作
可以把原子操作理解成:不需要用到互斥量加锁(无锁)技术的多线程并发编程方式。也可以理解成在多线程中不会被打断的程序执行片断。原子操作在效率上,比互斥量更胜一筹。
互斥量:一般是加锁一个代码段(几行代码,或者一片代码)。
原子操作:针对的是一般都是一个变量,而不是一个代码段。一般都是指不可分割的操作,要么是完成的,要么是没有完成的,不可能是中间状态(半完成状态)。
C++11中,std::atomic 表示原子操作,std::atomic 是一个类模板,其实std::atomic 这个东西用来封装某个类型指的。
//互斥量版本
#include <iostream>
#include <future>
#include <vector>
using namespace std;
int g_mycount = 0;
std::mutex g_mutex;
void mythread()
{
for (int i = 0; i < 1000000; i++)
{
g_mutex.lock();
g_mycount++;
g_mutex.unlock();
}
return;
}
int main()
{
cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
thread mytobj1(mythread);
thread mytobj2(mythread);
mytobj1.join();
mytobj2.join();
cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;
cout << "I Love China!" << endl;
return 0;
}
原子操作版本:
demo1:
#include <iostream>
#include <future>
#include <vector>
using namespace std;
atomic<int> g_mycount = 0; //封装了一个类型为int的对象(指),我们可以像操作一个int类型的变量,一样来操作g_mycount。
std::mutex g_mutex;
void mythread()
{
for (int i = 0; i < 1000000; i++)
{
//g_mutex.lock();
g_mycount++; //对应的操作是原子操作(不会被打断)
//g_mutex.unlock();
}
return;
}
int main()
{
cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
thread mytobj1(mythread);
thread mytobj2(mythread);
mytobj1.join();
mytobj2.join();
cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;
cout << "I Love China!" << endl;
return 0;
}
demo2:
#include <iostream>
#include <future>
#include <vector>
#include <atomic>
#include <thread>
using namespace std;
std::atomic<bool> g_ifend(false); // Linux
//std::atomic<bool> g_ifend(false); windows
void mythread()
{
chrono::milliseconds dura(1000);
while (g_ifend==false)
{
//系统没有要求线程退出,所以本线程可以干自己想干的事情
cout << "thread id=" << this_thread::get_id()<< "运行中" << endl;
std::this_thread::sleep_for(dura);
}
cout << "thread id=" << this_thread::get_id()<< "运行结束..." << endl;
return;
}
int main()
{
cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
thread mytobj1(mythread);
thread mytobj2(mythread);
std::chrono::milliseconds dura(5000);
std::this_thread::sleep_for(dura);
g_ifend = true;
mytobj1.join();
mytobj2.join();
cout << "I Love China!" << endl;
return 0;
}

浙公网安备 33010602011771号