一、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>
-
- using namespace std;
-
- atomic<int> g_ifend = false;
-
- 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;
- }