如何销毁由 std::thread 显式创建的线程?
Posted
技术标签:
【中文标题】如何销毁由 std::thread 显式创建的线程?【英文标题】:how to destroy a thread explicitly created by std::thread? 【发布时间】:2015-01-12 09:23:15 【问题描述】:我希望两个线程最初都在无限循环中运行,但一段时间后我想杀死第一个线程而不等待它完成,第二个应该正常运行。我该如何实施? 当我运行下面的代码时,它给出了调试错误!
void f1(int i)
while (1)
printf("Executng Thread %d : %d\n", i, j);
Sleep(10);
int main()
std::thread t1(f1, 1);
std::thread t2(f1, 2);
Sleep(100);
t1.~thread();
while (1)
Sleep(10);
return 0;
【问题讨论】:
你可以通过从你的计算机上拔掉插头来实现“只是杀死一些东西”。如果您希望能够对程序的行为进行确定性推理,那么您需要实现适当的控制流,而不仅仅是四处寻找。 @KerrekSB 你必须在单独的计算机上运行每个线程。 可能是重复的? ***.com/questions/26626882/… @JosephMansfield:我认为一旦你的程序是非确定性的,你就无法真正区分一个线程被杀死和所有线程被杀死(通常)。因此,拔掉插头实际上确实达到了预期的效果,并且无法通过单独使用语言规则与任何其他实现这种效果的方式来区分:-) 【参考方案1】:程序按照一组控制流执行一组确定的指令。你不能任意中断这个控制流,并且仍然对你的程序行为进行推理。
就像你不能说“运行我的程序,但不超过 10 秒”,程序不知道这一点并产生有意义的输出,你不能在线程不知道并产生有意义的程序状态的情况下杀死线程。简而言之,“线程取消需要合作”。
这里有一个让你的线程合作的简单方法:使用共享标志。
#include <atomic>
#include <chrono>
#include <thread>
std::atomic<bool> thread_1_must_end(false);
void foo(int thread_id)
while (true)
if (thread_id == 1 && thread_1_must_end.load()) break;
// do stuff
int main()
using std::literals::chrono_literals;
std::thread t1(foo, 1), t2(foo, 2);
std::this_thread::sleep_for(500ms);
thread_1_must_end.store(true);
t1.join(); // 1
// ...
请注意,此过程仍然是合作的。 join()
操作(标记为// 1
)阻塞,直到线程函数循环并检查标志。对此没有时间保证。如果线程函数忽略该标志,则无法与其通信。 您有责任为所有线程函数提供足够的设施,以便在何时结束时进行学习。
【讨论】:
我对“join() 操作(标记为 // 1)会阻塞,直到线程函数循环并检查标志”有疑问。会不会阻塞线程,直到标志为假,其他线程退出死循环? @Vinzenz:我不确定我是否遵循... :-S 两个线程同时运行相同的线程函数。在这个例子中,我什至没有处理线程 2。 听起来第一个线程只会“等待” t1 线程,直到它“循环并检查标志”。无论标志是真还是假,它都会继续异步到 t1 线程。我不熟悉std:atomic,所以我不知道线程是否是这样的。 @Vinzenz:线程 1 在看到thread_1_must_end
等于 true
时退出(通过中断循环)。那是t1.join()
返回的时候。
对,我也是这么学的。我仍然没有这种感觉,因为您通常使用线程来运行异步或并行的东西......所以我总是分离线程以上是关于如何销毁由 std::thread 显式创建的线程?的主要内容,如果未能解决你的问题,请参考以下文章
OpenMP、MPI、POSIX 线程、std::thread、boost::thread 如何关联?