C++ 标准库 std::thread 的用法和实现

作者: , 共 1060 字 , 共阅读 0

std::thread是 C++ 11 新引入的标准线程库。在同样是 C++ 11 新引入的 lambda 函数的辅助下,std::thread用起来特别方便:

int a = 1;
std::thread thread([a](int b) {
    return a + b;
}, 2);

它唯一有点令人疑惑的地方在于其提供的joindetach函数,字面上的意思是前者合并线程,后者分离线程。无论是合并还是分离,都会导致std::thread::joinable()返回false,而在此之前为true(即使这个新建线程的任务已经执行完毕!)。

合并线程的含义比较清楚,就是绑定的线程合并到当前线程执行,当前线程被堵塞,直到被合并的线程执行完毕。

分离线程则是新创建的线程和std::thread对象分离,创建的线程独立运行。std::thread将不再持有该线程。有人可能觉得这种毫无意义,但理论上还是有的,比如分离后,我们就可以析构std::thread对象,而不会影响创建的线程(创建的线程会继续运行)。

int a = 1;

{
    std::thread thread1([a](int b) {
        return a + b;
    }, 1);

    thread1.detach();
}

{
    std::thread thread2([a](int b) {
        return a + b;
    }, 2);
}

以上面代码为例,thread1不会出错,但thread2会导致程序退出。原因是std::thread的析构函数里设置了如果线程既没有合并也没有分离,程序就会自动退出!

~thread() {
    if (joinable()) std::terminate();
}

其源代码位于https://gcc.gnu.org/onlinedocs/gcc-7.5.0/libstdc++/api/a00158_source.html,实现非常简单,是基于pthread的封装,其内容只有线程 ID :

class thread {
public:
    typedef __gthread_t native_handle_type;
    class id {
        native_handle_type   _M_thread;
    };

private:
    id _M_id;
}

Q. E. D.

类似文章:
编程 » C++, 异步
C++11 的标准异步库至少包含下面内容:
编程 » C++
要在C++中运行系统命令,可以直接使用std::system函数:
智能指针在现代 C++里用得越多。以前只知道它大致的原理,比如使用引用计数。但很多实现细节并不清楚,最直接的,它是如何实现多线程安全的?今天找了 gnu c++ library 的实现好好看了一下。
看到网上有片段,提到没有必要自己实现自旋锁,因为标准库的 std::mutex 和现在的自旋锁的实现没有两样。比较好奇,翻了一些资料,试图找到答案。
编程 » C++, C++标准库
std::tuple的原理并不复杂,但有些细节非常有意思。其中有一个是至少在gnu C++ std的实现中,std::tuple是倒序存储的:
编程 » C++, 智能指针
前面已经提到std::shared_ptr有三个缺陷:
编程 » C++, 智能指针
理论上而言,当 C++提供了std::unique_ptr, C++的程序就不应该出现普通指针了。所有普通指针都可以用std::unique_ptr代替,避免手动删除对象。
编程 » C++,
C++的多行宏有标准定义方式,boostfolly库都采用了这种方式:
由 Facebook 开发和维护的 C++库 Folly 提供了自旋锁的实现folly::MicroSpinLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/synchronization/MicroSpinLock.h
编程 » C++, GCC, 编译链接
LD 在链接生成目标文件时,会从左到有扫描输入的依赖库,当依赖库之间也有依赖关系时,必须将「依赖别人的库」放在「被别人依赖的库」的前面。否则会链接失败!失败的症状有:
编程 » C++, gcc
follyLikely.h文件提供了 LIKELY 和 UNLIKELY 宏,提示编译器在分支预测时选择分支。其实现很简单
编程 » folly, C++, 数据容器
由 Facebook 开发和维护的 C++库 Folly 提供folly::small_vector,代码文件地址:https://github.com/facebook/folly/blob/master/folly/small_vector.h