「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 对象同一时间只能拥有一个线程的归属权。
运行结果如下: