「C++ 多线程」线程归属权及其转移
文章大图来源: pixiv_id=77108212
线程归属权
基本概念
在 C++ 中,线程归属权是指对线程对象生命周期的控制。当一个线程被创建后,需要确保它被正确地管理。
当我们用 std::thread 类创建了一个线程 t,那么 t 对象就拥有对所创建的新的子线程的归属权。在之后我们可以调用 join() 来等待子线程执行完毕;也可以调用 detach() 将现场分离,在后台独立运行,此时 t 对子线程的归属权被转移。
1 | |
线程归属权的转移
C++11 引入的移动语义在线程归属权转移上有着重要的作用。std::thread 线程对象是可移动的,但不可拷贝。
1 | |
在上面的代码中,t2 = std::move(t1) 将 t1 所代表的线程的归属权转移到了 t2。然后,t1 不再拥有线程的归属权,而 t2 负责管理线程的执行和生命周期,关联的是函数 foo(),之后我们选择调用 join() 等待线程 t2 执行完毕。
运行结果如下:

接下来再看一个复杂一点的示例:
1 | |
在上面的代码中,创建了一个 std::thread 对象 t1,并将函数 foo1 作为线程接口函数。然后通过 std::thread t2(std::move(t1)) 将 t1 所拥有的线程归属权转移给了 t2。此时,t1 变成空线程,t2 关联 foo1。
之后,通过 t1 = std::thread(foo2) 使得 t1 重新关联了另一个函数 foo2。
通过 t3 = std::move(t2) 将 t2 的线程归属权转移给 t3。此时 t2 变成空线程,t3 关联函数 foo1。
在注释的代码中的 t1 = std::move(t3); 操作是不可行的。t1 拥有一个线程的归属权(关联着 foo2 对应的线程)且还未执行结束(还未 join 或 detach)。
一个 std::thread 对象同一时间只能拥有一个线程的归属权。
运行结果如下:
