试图理解 C++ 中的线程
Posted
技术标签:
【中文标题】试图理解 C++ 中的线程【英文标题】:Trying to understand threading in C++ 【发布时间】:2015-07-26 18:08:39 【问题描述】:我是一名 C# 程序员,我现在需要用 C++ 创建一个程序。我想要实现的是制作一个无限线程并给它一个睡眠时间。
在c#中我可以很容易地做到这一点
在主函数中
new Thread(taskfunction).Start();
和任务功能
private void taskfunction()
while(true)Thread.Sleep(2500); // do stuff
所以只要我的程序打开,这将在后台运行。我正在尝试在 C++ 中实现相同的目标,例如:
在主函数中
std::thread somethread(taskfunction);
somethread.join();
和任务功能
void taskfunction()
while(true)this_thread::sleep_for(chrono::milliseconds(2500));// Do Stuff
因此,当 c# 线程启动并继续运行时,c++ 线程等待 somethread.join();
。有什么区别,我如何才能在 c# 中实现我在 c++ 中所做的事情?
谢谢
【问题讨论】:
实际上你必须在 C# 和 C++ 中加入或分离你的线程join
表示“等到线程完成”。那不是你想要的。您可以detach
单独留下另一个线程,或者稍后将std::thread
-object 放在join
的某个位置。只是不要在没有join
ing 或detach
ing 的情况下破坏std::thread
-object。
【参考方案1】:
std::thread::join() 阻塞当前执行线程,直到您调用它的线程完成它的执行(从线程过程返回)。
这很有用,如果(例如)您想创建临时线程,它应该执行一些计算并生成结果,您可以等待并立即使用。
在您的情况下,您不应该使用此方法 - 至少不要在线程创建后立即使用。但是请注意,std::thread
必须加入或分离:
std::thread::~thread()
销毁线程对象。
如果
*this
有关联的线程 (joinable() == true
),则调用std::terminate()
。
所以你需要:
detach()线程是否应该独立于主线程执行(线程分配的资源将在线程执行完毕后自动释放) 继续main()
,当您到达程序末尾时,向线程发出信号,告知它应该结束,然后join()
它。
【讨论】:
分离是危险的。您需要进行一些设置以等待线程安全完成,在这种情况下,您最好始终使用 join。 加入是危险的。等待线程完成很容易导致进程不会关闭。永远不要使用 join(),使用应用程序生命周期线程/线程池并且永远不要显式终止线程,这要好得多。操作系统在终止线程方面比任何用户代码都要好得多,如果可能的话,应该允许在进程终止时这样做。 @MartinJamesjoin
只有在你编写一个永不结束的线程函数时才能做到这一点。你不应该写一个永不结束的线程函数。 join
鼓励编写好的代码,安全结束的线程函数(通常由另一个线程发出信号)。 detach
鼓励编写不安全的代码。这与线程何时在操作系统级别终止无关,因为在 99% 的情况下,性能问题不是问题,而是与定义良好的代码范围有关。
??几十年来,我一直在编写应用程序生命周期线程,没问题。当开发人员出现更多问题。尝试在进程结束之前终止线程,而不是在进程结束时终止线程。仅举一个例子,GUI 框架不能在偶数处理程序中等待任何事情,包括在线程上调用 join(),这些线程可能会或可能不会很快终止,或者更糟糕的是,它们本身正在等待 GUI 框架排队的某些操作,(死锁)。
@MartinJames 我看不到线程的使用情况,即在之后 main()
开始并在 main()
完成之后结束。对我来说,这显然是线程层次结构的缺陷。我总是强制线程与其子线程同步(加入),这确保了正确的执行流程并有助于资源管理(您为每个对象定义了明确的生命周期)。 join()
确实有助于实现这些方面。由于它会阻塞,因此很危险 - 但正确使用会非常有帮助。【参考方案2】:
您可以detach()
线程使其独立。
【讨论】:
【参考方案3】:使用 std::tread::detach()。此函数将执行线程与线程对象分离,允许执行独立继续。一旦线程退出,所有分配的资源都将被释放。
【讨论】:
以上是关于试图理解 C++ 中的线程的主要内容,如果未能解决你的问题,请参考以下文章