如果我创建GUI
并且每个小部件由thread
控制,那么一个线程会使GUI死锁吗?
据我所知,如果它是一个GUI,在某个时间只显示一个数字并且该数字由一个线程确定(比如t0)那么所有其他线程(t1 ... tN)将等待这一个&# 39; s过程结束,因此如果t0发生错误,它将使孔GUI死锁 它可以用独立的小部件来解决吗?
可以使用pthread
库在c中完成吗?
答案 0 :(得分:1)
除非你非常好或非常幸运,否则你很可能在某些时候陷入僵局。
让每个小部件都在自己的线程中听起来比单线程更快,但它非常复杂。通常,用户输入和绘制窗口小部件不会成为瓶颈,因此将每个窗口小部件放在不同的线程中会给您带来很多复杂性,而这些复杂性并不值得。
GUI通常有一个主循环,用于处理鼠标移动,鼠标点击,按下按钮,系统事件等事件。如果您需要执行需要执行的操作,那么您将在工作线程中运行这些操作但是不处理该工作线程中的窗口小部件事件或任何GUI相关事件。
如果你想尝试它,你需要在所有地方进行同步,我认为你很快就会认为它不值得付出努力,因为每个线程都会尝试为它的小部件处理事件。绝对只有专家才应该尝试。
答案 1 :(得分:0)
不要惊慌。
遵守以下规则/指南:
1)坚持使用GUI系统的一个线程,处理消息和调用事件。无论如何,这是强制执行我的大多数GUI框架。
2)永远不要以任何方式在GUI事件处理程序中等待任何线程信号或状态。使用框架消息传递系统(信号/插槽,Windows消息等)与其他线程进行数据通信。
3)不要不断创建/终止/销毁/加入线程。永远不要这样做。如果您的“多线程简介”网站说您必须始终使用join join()等待线程终止,请从浏览器中删除对该网站的所有引用及其历史记录。使用池化或dedidated到一个任务的app-lifetime线程,并循环一些阻塞输入队列机制并处理输入消息,直到应用程序终止。除非你完全没有选择或者你喜欢痛苦,否则不要试图自己将它们自己定位。
4)'我决定为每个新客户打开一个帖子。收到的数据将显示在GUI'上。很好,听起来像一个计划。对于表示单个客户端的每个窗口小部件组,启动一个线程来处理通信,并作为线程创建的一部分,传递绑定到的窗口小部件组的实例,以便它可以将消息定向回正确的窗口小部件,以及某种队列事件/线程可以等待排队输入请求结构的任何内容。
5)不要直接从GUI线程写入任何数据/字段/任何客户端线程。如果要从GUI线程传达某些内容,请使用框架和/或OS API将请求结构排队到线程。
6)不要从客户端线程写入任何数据/字段/任何GUI线程。如果要与GUI线程进行通信,请使用框架和/或OS API将请求结构消息排队到线程,因此使用消息触发事件处理程序以执行GUI操作。
7)注意消息的生命周期 - 如果你打算将消息结构指针排队到另一个线程,那么使用自动存储分配结构是没用的 - 它可能会在接收线程获取它时消失。一种方法:malloc它,将它排队到另一个线程,接收它,在另一个线程中释放它。其他的,矿石控制的线程间,GUI间通信机制是可能的,例如。使用消息池,但我怀疑这超出了你的身份。
7)如果可能的话,设计避免app-lifetime和池中线程的“干净和优雅终止”。用户代码无法可靠地阻止在其他核心上运行的线程(没有杂乱和浪费的轮询)。操作系统可以在进程终止时轻松停止所有线程 - 让它完成它的工作。
8)忘记许多那些只编写过单线程命令行应用程序的“必须做”规则。例如,您的代码总是释放在程序运行期间分配的所有内存,这是非常不现实的。在一个复杂的应用程序中,有多个内核读/写消息等,任何编写用户代码以关闭它的尝试都极有可能产生更多的问题,在测试/调试方面是值得的。如果你分配了一些东西并且你需要它来进行整个运行,那么就这样做 - 不要试图释放它,充其量没有意义。如果多个线程正在读/写/通过它进行调用,那么就会有一个大量的测验显示 - 完全没有使用用户代码释放它的点(操作系统可以在终止时轻松释放它 - 它会在处理进程之前先停止所有线程存储器)。
如果你只排队请求/消息,不要在事件处理程序中等待并且不进行任何类似join()的自杀调用,你应该没有死锁:)