设为首页 加入收藏

TOP

C++ std::thread概念介绍(二)
2019-09-23 11:11:31 】 浏览:105
Tags:std::thread 概念 介绍
ef
(arg)); // pass to thread by reference std::thread t4(std::move(t3)); // t4 is now running func2(). t3 is no longer a thread //t1.join() Error! t2.join(); //t3.join() Error! t4.join(); }

多数情况下我们使用的是上面第二种创建线程的方式。下面看一下join和detach。

4.2  join && detach

对于创建的线程,一般会在其销毁前调用join和detach函数;

弄清楚这两个函数的调用时机和意义,以及调用前后线程状态的变化非常重要。

  • join 会使当前线程阻塞,直到目标线程执行完毕;
    • 只有处于活动状态线程才能调用join,可以通过joinable()函数检查;
    • joinable() == true表示当前线程是活动线程,才可以调用join函数;
    • 默认构造函数创建的对象是joinable() == false;
    • join只能被调用一次,之后joinable就会变为false,表示线程执行完毕;
    • 调用 ternimate()的线程必须是 joinable() == false;
    • 如果线程不调用join()函数,即使执行完毕也是一个活动线程,即joinable() == true,依然可以调用join()函数;
  • detach 将thread对象及其表示的线程分离;
    • 调用detach表示thread对象和其表示的线程完全分离;
    • 分离之后的线程是不在受约束和管制,会单独执行,直到执行完毕释放资源,可以看做是一个daemon线程;
    • 分离之后thread对象不再表示任何线程;
    • 分离之后joinable() == false,即使还在执行;

join实例分析

int main() {
    thread t(tstart, "C++ 11 thread!");
    cout << t.joinable() << endl;
    if (t.joinable()) t.join();
    //t.detach(); Error
    cout << t.joinable() << endl;
    // t.join(); Error
    cout << "Main Function!" << endl;
    system("pause");
}

简单来说就是只有处于活动状态的线程才可以调用join,调用返回表示线程执行完毕,joinable() == false.

inline void thread::join()
    {    // join thread
    if (!joinable())
        _Throw_Cpp_error(_INVALID_ARGUMENT);
    const bool _Is_null = _Thr_is_null(_Thr);    // Avoid Clang -Wparentheses-equality
    ... ...
}

将上面的t.join()换成是t.detach()会得到相同的结果.

void detach()
    {   // detach thread
    if (!joinable())
        _Throw_Cpp_error(_INVALID_ARGUMENT);
    _Thrd_detachX(_Thr);
    _Thr_set_null(_Thr);
    }

上面是thread文件中对detach的定义,可以看出只有joinable() == true的线程,也就是活动状态的线程才可以调用detach。

~thread() _NOEXCEPT
    {   // clean up
    if (joinable())
        _XSTD terminate();
    }

当线程既没有调用join也没有调用detach的时候,线程执行完毕joinable() == true,那么当thread对象被销毁的时候,会调用terminate()。

4.3 获取线程ID

线程ID是一个线程的标识符,C++标准中提供两种方式获取线程ID;

  1. thread_obj.get_id();
  2. std::this_thread::get_id()

有一点需要注意,就是空thread对象,也就是不表示任何线程的thread obj调用get_id返回值为0;

此外当一个线程被detach或者joinable() == false时,调用get_id的返回结果也为0。

cout << t.get_id() << ' ' << this_thread::get_id() << endl;
//t.detach();
t.join();
cout << t.get_id() << ' ' << std::this_thread::get_id() << endl;

4.4 交换thread表示的线程

除了上面介绍的detach可以分离thread对象及其所表示的线程,或者move到别的线程之外,还可以使用swap来交换两个thread对象表示的线程。

实例来看一下两个线程的交换。

int tstart(const string& tname) {
    cout << "Thread test! " << tname << endl;
    return 0;
}

int main() {
    thread t1(tstart, "C++ 11 thread_1!");
    thread t2(tstart, "C++ 11 thread_2!");
    cout << "current thread id: " << this_thread::get_id() << endl;
    cout << "before swap: "<< " thread_1 id: " << t1.get_id() << " thread_2 id: " << t2.get_id() << endl;
    t1.swap(t2);
    cout << "after swap: " << " thread_1 id: " << t1.get_id() << " thread_2 id: " << t2.get_id() << endl;
    //t.detach();
    t1.join();
    t2.join();
}

结果:

Thread test! C++ 11 thread_1!
Thread test! C++ 11 thread_2!
current thread id: 39308
before swap:  thread_1 id: 26240 thread_2 id: 37276
after swap:  thread_1 id: 37276 thre
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇最好的重试是指数后退和抖动 下一篇【C/C++】qsort函数的使用方法和..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目