美文网首页
线程管理

线程管理

作者: wenmingxing | 来源:发表于2018-04-23 19:45 被阅读15次

    本文主要内容包括:启动新线程;等待线程与分离线程;线程唯一标识符。

    I、线程管理的基础

    每个线程都有各自的入口函数。最简单情况下,任务通常是无参数无返回值的函数。这个函数在其所属的线程上运行,直到函数执行完毕,线程也就结束了。

    1.1 启动线程

    使用C++线程库启动线程,可以归结为构造std::thread对象,std::thread可以用可调用类型构造,将带有函数调用符类型的实例传入thread类中,替换默认的构造函数,下面的代码使用函数对象来完成对thread的构造:

    class background_task {
    public:
        void operator()() const {
            do_something();
            do_something_else();
        }
    };
    
    background_task f;    //必须使用一个命名的变量
    std:::thread my_thread(f);
    

    这里需要注意一个问题,当把函数对象传入到线程的构造函数中时,需要避免一些语法解析问题:如果传递了一个临时变量,而不是一个命名的变量,C++编译器会将其解析为函数声明,而不是类型对象的定义:

    std::thread my_thread(background_task());
    这里相当于声明了一个名为my_thread的函数,返回一个thread对象,而非启动了一个线程。

    可以通过以下两种方式解决这个问题:

    std::thread my_thread((background_task()));
    std::thread my_thread{background_task()};  //新统一的初始化语法
    

    或者使用lambda表达式

    std::thread my_thread([] {
        do_something();
    });
    
    1.2 join 与 detach

    1、join函数为等待线程完成,确保线程在函数完成前结束,并且只能对一个线程使用一次join

    2、detach会让线程在后台运行,这就意味着主线程不能与之产生直接交互。不会等待这个线程结束。

    3、joindetach的区别可以理解为:在调用方法之后,主线程是否还有对线程的控制权

    II、向线程函数传递参数

    #include<thread>
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    void print(string& str) {
        cout << str << endl;
    }
    
    int main() {
        string str = "hello";
        thread th1(print, ref(str));     //需要确保传入print的参数与其定义的引用一致
    
        th1.join();
    
        return 0;
    }
    

    III、转移线程所有权

    执行线程的所有权可以在std::thread实例中移动,下面是一个例子:

    void some_function();
    void some_other_function();
    std::thread t1(some_function);
    std::thread t2 = std::move(t1);
    t1 = std::thread(some_other_function);
    std::thread t3;
    t3 = std::move(t2);
    t1 = std::move(t3);
    

    IV、识别线程

    调用get_id()方法可以直接获取线程id:

    #include<thread>
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    void print(string str) {
        cout << str << endl;
    }
    
    int main() {
        cout << this_thread::get_id() << endl;  //通过this_thread获得当前线程标识
    
        thread th1(print, "id");
    
        cout << th1.get_id() << endl;   //通过get_id识别线程
        th1.join();
    
        return 0;
    }
    

    【参考】
    [1] 《C++ Concurrency In Action》

    相关文章

      网友评论

          本文标题:线程管理

          本文链接:https://www.haomeiwen.com/subject/lpellftx.html