• future其他成员函数、shared_future、atomic


    一、future其他成员函数

    线程的三种状态。1.ready 2.time_out 3.deferred

    1. #include <iostream>
    2. #include <future>
    3. #include <vector>
    4. using namespace std;
    5. int mythread()
    6. {
    7. cout << "int mythread() start,thread id=" << std::this_thread::get_id() << endl;
    8. chrono::milliseconds dura(5000);
    9. this_thread::sleep_for(dura);
    10. cout << "int mythread() end,thread id=" << std::this_thread::get_id() << endl;
    11. return 5;
    12. }
    13. int main()
    14. {
    15. cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
    16. //future<int> result = async(std::launch::deferred,mythread); //launch::deferred 不会创建子线程,是和主线程是一个线程
    17. future<int> result = async(mythread);
    18. cout << "continue...!" << endl;
    19. //cout << result.get() << endl;
    20. future_status status = result.wait_for(chrono::seconds(6));
    21. if (status == future_status::timeout) //超时:表示线程还没执行完,希望1秒钟内就返回,但是没有返回,此时就会超时;
    22. {
    23. cout << "超时了,线程还没有执行完." << endl;
    24. }
    25. else if (status == future_status::ready)
    26. {
    27. cout << "表示线程成功返回了." << endl;
    28. }
    29. else if (status == future_status::deferred) // async 的第一个参数是std::launch::deferred 的话,这个条件就会成立。
    30. {
    31. cout << "async 的第一个参数是std::launch::deferred.,线程被延迟执行." << endl;
    32. cout << result.get() << endl;
    33. }
    34. cout << "I Love China!" << endl;
    35. return 0;
    36. }

    二、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 这个东西用来封装某个类型指的。

    //互斥量版本

    1. #include <iostream>
    2. #include <future>
    3. #include <vector>
    4. using namespace std;
    5. int g_mycount = 0;
    6. std::mutex g_mutex;
    7. void mythread()
    8. {
    9. for (int i = 0; i < 1000000; i++)
    10. {
    11. g_mutex.lock();
    12. g_mycount++;
    13. g_mutex.unlock();
    14. }
    15. return;
    16. }
    17. int main()
    18. {
    19. cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
    20. thread mytobj1(mythread);
    21. thread mytobj2(mythread);
    22. mytobj1.join();
    23. mytobj2.join();
    24. cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;
    25. cout << "I Love China!" << endl;
    26. return 0;
    27. }

    原子操作版本:

    demo1:

    1. #include <iostream>
    2. #include <future>
    3. #include <vector>
    4. using namespace std;
    5. atomic<int> g_mycount = 0; //封装了一个类型为int的对象(指),我们可以像操作一个int类型的变量,一样来操作g_mycount。
    6. std::mutex g_mutex;
    7. void mythread()
    8. {
    9. for (int i = 0; i < 1000000; i++)
    10. {
    11. //g_mutex.lock();
    12. g_mycount++; //对应的操作是原子操作(不会被打断)
    13. //g_mutex.unlock();
    14. }
    15. return;
    16. }
    17. int main()
    18. {
    19. cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
    20. thread mytobj1(mythread);
    21. thread mytobj2(mythread);
    22. mytobj1.join();
    23. mytobj2.join();
    24. cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;
    25. cout << "I Love China!" << endl;
    26. return 0;
    27. }

    demo2:

    1. #include <iostream>
    2. #include <future>
    3. #include <vector>
    4. using namespace std;
    5. atomic<int> g_ifend = false;
    6. void mythread()
    7. {
    8. chrono::milliseconds dura(1000);
    9. while (g_ifend==false)
    10. {
    11. //系统没有要求线程退出,所以本线程可以干自己想干的事情
    12. cout << "thread id=" << this_thread::get_id()<< "运行中" << endl;
    13. std::this_thread::sleep_for(dura);
    14. }
    15. cout << "thread id=" << this_thread::get_id()<< "运行结束..." << endl;
    16. return;
    17. }
    18. int main()
    19. {
    20. cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
    21. thread mytobj1(mythread);
    22. thread mytobj2(mythread);
    23. std::chrono::milliseconds dura(5000);
    24. std::this_thread::sleep_for(dura);
    25. g_ifend = true;
    26. mytobj1.join();
    27. mytobj2.join();
    28. cout << "I Love China!" << endl;
    29. return 0;
    30. }

  • 相关阅读:
    Java接口练习
    C陷阱与缺陷 第6章 预处理器 6.4 宏并不是类型定义
    打家劫舍问题
    unity游戏开发中的随机算法
    linux下tomcat怎么部署war包
    代码随想录1刷—算法性能分析摘记
    高效代码静态测试工具Klocwork 2022.3版本快讯
    力扣623.在二叉树中增加一行 dfs
    DW大学生网页作业制作设计 ——旅游门户网站(21页)HTML+CSS+JavaScript
    列表和标签企业报告版的完整报告解决方案
  • 原文地址:https://blog.csdn.net/weixin_42136255/article/details/124973752