zoukankan      html  css  js  c++  java
  • 线程管理_tmp

    线程管理

    thread管理基础

    thread_join_detach.cpp

    • 线程启动后,销毁前要调用joindetach,否则std::thread的析构函数会调用std::terminate终止程序.
    • 线程都有入口函数,入口main/foo 函数.
    • 线程会在函数结束时完会退出.
    • 使用join即可保证局部变量在线程结束后才被销毁.
    • 将函数添加为std::thread的参数即可启动线程
    • join过的std::thread joinable()为false,故不能再次被join
    • 分离线程称为守护线程,即没有任何显式接口并运行在后台的线程,其特点是长时间运行。
    class A{
        int _value;
    public:
        A(int value):_value(value){std::cout<<"A("<<_value<<")"<<endl;}
        ~A(){std::cout<<"~A("<<_value<<")"<<endl;}
        int value() const { return _value; }
    };
    
    void foo(int value){
        system_clock::time_point  startTimer  = std::chrono::high_resolution_clock::now();
        std::cout << "starting sub thread =" << std::this_thread::get_id()<<"\tvalue =" << value<<endl;
        std::this_thread::sleep_for(std::chrono::seconds(value));
        PrintExitInfo(startTimer);
    }
    void foo_join(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        thread1.join();   // foo_join所在线程,等待线程thread1完成执行
        //保证局部变量obj在线程thread1结束后才被销毁.
    }
    
    void foo_detach(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        thread1.detach();   // 允许线程独立于foo_detach所在线程执行
        //变量obj被销毁,thread1可能还在运行.
    }
    void test_terminate(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        //thread1的析构函数会调用std::terminate终止程序,obj未被销毁.
    }
    int main()
    {
        A obj{0};
        std::cout << "starting main thread =" << std::this_thread::get_id()<<endl;
        system_clock::time_point startTimer = std::chrono::high_resolution_clock::now();
    //    test_terminate(1);
        foo_detach(5);
        foo_join(3);
        PrintExitInfo(startTimer);
    
        return 0;
    }
    
    
    • A(0)
      starting main thread =1
      A(5)
      ~A(5)
      A(3)
      starting sub thread =2	value =5
      starting sub thread =3	value =3
      Exiting thread =3	duration:3011.49 ms
      ~A(3)
      Exiting thread =1	duration:3011.55 ms
      ~A(0)
      

    为线程函数传递参数

    • 有参数的函数也能传给std::thread,参数的默认实参会被忽略
    • std::thread会无视参数的引用类型,因此需要使用std::ref来生成一个引用包裹对象以传入引用类型
    • 也可以传递类成员函数
    • 如果参数是move-only对象则需要使用std::move
    void f(int i = 1){  std::cout << i <<endl;}
    void Func(int& n) { ++n; std::cout << n <<endl; }
    struct AA {
        void f(int i) { std::cout << i<<endl; }
    };
    void FuncPoint(std::unique_ptr<int> p)
    {
        std::cout << *p<<endl;
    }
    int main()
    {
        int i = 1;
        std::thread t(f, i); // 第一个参数为函数名,其余参数为函数的参数
        t.join();
    
        std::thread t2(Func, std::ref(i));
        t2.join();
    
        AA a;
        std::thread t3(&AA::f, &a, 42); // 第一个参数为成员函数地址,第二个参数为实例地址
        t3.join();
    
        std::unique_ptr<int> p(new int(43));
        std::thread t4(FuncPoint, std::move(p));
        t4.join();
    }
    

    线程标识

    //std::thread::hardware_concurrency();  //支持的并发线程数
    std::thread::id masterThread; // 主线程
    int main()
    {
        masterThread = std::this_thread::get_id();
    }
    

    转移线程所有权

    void g();
    void f(int i) { std::cout << i; }
    
    std::thread gg()
    {
      return std::thread(f, 42);
    }
    int main()
    {
      std::thread t1(f);
    std::thread t2 = std::move(t1); // t1所有权给t2,t2关联执行f的线程
    t1 = std::thread(g); // t1重新关联一个执行g的线程
    std::thread t3;
    t3 = std::move(t2); // t3关联t2的线程,t2无关联
    t1 = std::move(t3); // t1已有关联g的线程,调用std::terminate终止程序
      
      std::thread t{gg()};
      t.join();
    }
    
    #include <iostream>
    #include <thread>
    #include <chrono>
    using namespace std;
    using namespace std::chrono;
    
    class A{
        int _value;
    public:
        A(int value):_value(value){std::cout<<"A("<<_value<<")"<<endl;}
        ~A(){std::cout<<"~A("<<_value<<")"<<endl;}
        int value() const { return _value; }
    };
    
    void PrintExitInfo(system_clock::time_point startTimer)
    {
        auto EndTimer = high_resolution_clock::now();
        duration<double, std::milli> fp_ms = EndTimer - startTimer;
        std::cout << "Exiting thread =" << std::this_thread::get_id() << "\tduration:"<< fp_ms.count() << " ms"<<endl;
    }
    
    void foo(int value){
        system_clock::time_point  startTimer  = std::chrono::high_resolution_clock::now();
        std::cout << "starting sub thread =" << std::this_thread::get_id()<<"\tvalue =" << value<<endl;
        std::this_thread::sleep_for(std::chrono::seconds(value));
        PrintExitInfo(startTimer);
    }
    
    void foo_join(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        thread1.join();   // foo_join所在线程,等待线程thread1完成执行
        //保证局部变量obj在线程thread1结束后才被销毁.
    }
    
    void foo_detach(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        thread1.detach();   // 允许线程独立于foo_detach所在线程执行
        //变量obj被销毁,thread1可能还在运行.
    }
    void test_terminate(int value){
        A obj{value};
        std::thread thread1(foo,obj.value());
        //thread1的析构函数会调用std::terminate终止程序,obj未被销毁.
    }
    
    int main()
    {
        std::thread::id masterThread; // 主线程
        masterThread = std::this_thread::get_id();
    
        A obj{0};
        std::cout << "starting main thread =" << masterThread <<endl;
        system_clock::time_point startTimer = std::chrono::high_resolution_clock::now();
        //    test_terminate(1);
        foo_detach(5);
        foo_join(3);
        PrintExitInfo(startTimer);
    
        return 0;
    }
    
    
    
  • 相关阅读:
    结队-贪吃蛇游戏-项目进度
    团队-象棋游戏-开发环境搭建过程
    团队-中国象棋游戏-设计文档
    结对-贪吃蛇游戏-开发环境搭建过程
    结对-结对编项目贪吃蛇-设计文档
    课后作业-阅读任务-阅读提问-1
    《20170911-构建之法:现代软件工程-阅读笔记》
    团队-中国象棋-成员简介及分工
    团队-团队编程项目中国象棋-需求分析
    结队-结队编程项目贪吃蛇--需求分析
  • 原文地址:https://www.cnblogs.com/yan1345/p/15703294.html
Copyright © 2011-2022 走看看