简体   繁体   English

如何休眠所有正在运行的线程 C++?

[英]How to sleep all running threads C++?

Problem问题

I want to stop the entire program process on a special event from GUI (Qt 5.15.2), except the GUI thread, and show an error message dialog and terminate the program.我想在 GUI (Qt 5.15.2) 的一个特殊事件上停止整个程序进程,除了 GUI 线程,并显示一个错误消息对话框并终止程序。

1) Problem With Getting All Running Threads 1)获取所有正在运行的线程的问题

I need to put all other running threads in sleep before they cause some problems like Segmentation Fault.我需要将所有其他正在运行的线程置于睡眠状态,然后才能导致诸如分段错误之类的问题。 With POSIX Thread APIs and MS-Windows APIs, we have a proper API for getting a list of all running threads.使用 POSIX 线程 API 和 MS-Windows API,我们有一个适当的 API 来获取所有正在运行的线程的列表。 But I don't find a similar one from STL.但我没有从 STL 中找到类似的。 Is there any cross-platform API (even from third-party libraries like Qt or Boost)?是否有任何跨平台 API(甚至来自 Qt 或 Boost 等第三方库)? Or I must implement using platform-specific APIs?或者我必须使用特定于平台的 API 来实现?

2) Problem With Putting All Running Threads In Sleep 2) 将所有正在运行的线程置于睡眠状态的问题

After getting the running threads, how could I put them to sleep while they are in the middle of some sort of blocking operations?获得正在运行的线程后,我怎么能在它们处于某种阻塞操作中间时让它们进入睡眠状态? It's possible?这是可能的?

In general what you are asking for is not possible, at least not without keeping your own list of active threads and co-operating with them to achieve that result.一般来说,您所要求的东西是不可能的,至少在没有保留您自己的活动线程列表并与它们合作以实现该结果的情况下是不可能的。

For example, if your main/GUI thread keeps its own list of active threads (which it appends to whenever it spawns a thread, and removes from whenever it joins an exited thread), it could also maintain a list of QMutex objects (one per thread), and to "pause all threads" it could acquire every QMutex in the list.例如,如果你的主/GUI 线程保持它自己的活动线程列表(它在它产生一个线程时附加到它,并在它加入一个退出的线程时从中删除),它也可以维护一个QMutex对象列表(每个线程),并“暂停所有线程”,它可以获取列表中的每个QMutex That, by itself, wouldn't affect the threads at all, but if you had added code to each thread to periodically acquire and then immediately release its QMutex , then the next time the thread tried to acquire the QMutex it would block inside the acquire function until the main thread decided to release the QMutex again.这本身根本不会影响线程,但是如果您将代码添加到每个线程以定期获取然后立即释放其QMutex ,那么下次线程尝试获取QMutex ,它将在获取中阻塞直到主线程决定再次释放QMutex

That said, I don't think that sleeping all running threads is the proper solution to your problem anyway.也就是说,我不认为让所有正在运行的线程休眠是解决问题的正确方法。 If your problem is that threads are occasionally crashing when you try to exit your program, the proper solution to that problem is to perform a controlled shutdown : have your main thread ask all of the child threads to go away (via std::atomic<bool> or pipe() or socketpair() or condition-variable or whatever other mechanism is convenient) and then call join() on each of the child threads before exiting.如果您的问题是当您尝试退出程序时线程偶尔会崩溃,则该问题的正确解决方案是执行受控关闭:让您的主线程要求所有子线程离开(通过std::atomic<bool>pipe()socketpair()或条件变量或任何其他方便的机制),然后在退出之前在每个子线程上调用join() That way, when the main thread finally does exit, it is guaranteed that no child threads are running anymore, and thus there is no race condition possible between the main thread's cleaning up of resources and child threads trying to still use them.这样,当主线程最终退出时,可以保证不再有子线程在运行,因此在主线程清理资源和尝试仍然使用它们的子线程之间不存在竞争条件。

If your child threads are stuck inside blocking calls, that can be a problem, since the child threads can't exit until after their blocking calls have returned, and the main thread can't complete all of its calls to join() until all of the child threads have exited.如果您的子线程卡在阻塞调用中,这可能是一个问题,因为子线程直到阻塞调用返回后才能退出,并且主线程无法完成对join()所有调用,直到所有的子线程已退出。 One way to deal with that problem would be to put timeouts on the blocking calls, so that the child threads will periodically be able to unblock and see if they need to exit;处理该问题的一种方法是在阻塞调用上设置超时,以便子线程能够定期解除阻塞并查看它们是否需要退出; that's a bit ugly, though, so in my programs I try to use only non-blocking I/O instead (eg have the child threads only block inside select() or poll() , and when the main thread wants them to go away, it sends a byte on a pipe() that the child thread is selecting-for-read-ready on, to notify the child thread that it is time to exit ASAP)不过,这有点难看,所以在我的程序中,我尝试仅使用非阻塞 I/O(例如,让子线程仅在select()poll()内阻塞,并且当主线程希望它们消失时,它在子线程正在选择读取就绪的pipe()上发送一个字节,以通知子线程是时候尽快退出了)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM