http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html认为多线程GUI框架是一个失败的梦想。那么非GUI框架呢?这个经验法则是否扩展到所有事件驱动的框架?
以下引文引起了我的注意:
输入事件处理的问题在于它往往与大多数GUI活动的方向相反。通常,GUI操作从一堆库抽象的顶部开始并“向下”。我在我的应用程序中运行一个由一些GUI对象表示的抽象概念,所以我从我的应用程序开始,调用高级GUI抽象,调用较低级别的GUI抽象,调用丑陋的内容。工具包,然后进入操作系统。相比之下,输入事件从OS层开始,逐步向上调度抽象层,直到它们到达我的应用程序代码。
现在,由于我们使用抽象,我们自然会在每个抽象中单独进行锁定。不幸的是,我们有经典的锁定订单噩梦:我们有两种不同类型的活动,希望获得相反订单的锁定。所以僵局几乎是不可避免的。
答案 0 :(得分:7)
没有。即使按照经验,它只是简单地说“让它们起作用很困难”。但事件驱动的框架非常类似于事件驱动的模拟和其他各种事物; Javaworld中很难实现多线程的事实,而不是Java中可用的抽象。
在另一个环境中,比如Erlang,它既相当自然,也非常强大。
听起来他仍然有错误的抽象。我没有看到强制锁定问题的问题所固有的任何内容。我想,关键在于:
现在,因为我们正在使用抽象, 我们自然会做锁定 在每个抽象中分别。 不幸的是,我们有经典 锁定噩梦:我们有两个 正在进行的各种活动 想要获得相反的锁 命令。所以僵局差不多了 不可避免的。
那为什么僵局几乎不可避免?因为正在进行两种不同类型的活动,希望以相反的顺序获取锁。这是因为“我们自然会在每个抽象中单独锁定。”
换句话说,他选择 - 或者是环境中为他选择的 - 抽象不支持他的需要。他似乎声称,因此没有任何抽象。我觉得这不令人信服。我首先要研究两件事:
根据我的经验,“自然X”通常意味着“我还没有真正寻找其他选择。”而且我非常怀疑这些事件是想要以相反的顺序获得锁定;你得到一个锁,你做了什么,然后释放它。
关键是,他似乎在提出这样一个事实:他发现很难找到一个做的方案作为一个定理,说没有方案可以工作。
如果没有关于这个问题的更多细节,很难构建一个反例,但正如我上面所说的那样,有很多系统的例子都是从内部进程和GUI异步地进行事件的。 ,设法有许多并发控制线程,不会死锁。 Erlang浮现在脑海中,因为这类问题中的一类是电话,是Erlang被发明的问题,实际上这些问题是为什么 Erlang被发明出来的。
答案 1 :(得分:4)
我必须说不,有一个警告。围绕共享状态的事件驱动框架,例如UI,应该是单线程的。事件驱动的框架围绕通知,例如机械监控(例如,让管道中的压力过高时让你知道),可以是单线程的,但可能更适合多线程。
构建多线程UI框架当然是可能的,我自己也这样做了。最后我将它转换为单线程。部分原因确实属于查理所说的“太难了”。问题在于,使用多线程UI框架,不仅仅是 me 必须处理线程,而是使用UI的任何人。核心当然是线程安全的,但是编写控件的任何人都必须使 线程安全。没关系,当对UI进行多次更改时,您必须通知核心您正在这样做,因此您没有获得部分更新。由于用户通常是一件非常慢的事情,因此任何性能提升都可以忽略不计,并且如果特定情况需要,可以使用异步调用来解决。单线程实际上是这里适当的模型。
另一方面,在没有(或没有太多)共享状态的模型中,多线程模型具有显着的意义。没有理由将一个事件(反应堆着火)延迟30秒(查询操作员鲍勃)(因为操作中的某些雅虎操作使得打卡表被锁定)。
答案 2 :(得分:3)
我想知道有多少问题来自多线程不适合事件处理的事实,以及构建GUI的许多开发人员不熟悉多线程的程度是多少。
我倾向于支持后一种情况,还有一些框架的冗余。例如,我发现Eclipse中的GUI代码编写起来相当烦人,因为没有更方便的方法来处理繁重的逻辑和GUI代码。
答案 3 :(得分:1)
通常,是的,因为事件驱动的框架类似于Reactor模式,它规定了一个等待事件的主循环(“事件循环”,然后调用各个元素的注册回调。
这就是传统上定义事件驱动框架的方式。 以下是关于Erlang进程如何与VM的事件循环相关联的一个很好的描述:
Erlang进程与Erlang VM的事件驱动的网络IO核心紧密集成。进程可以“拥有”套接字并向/从套接字发送和接收消息。这提供了面向并发编程的优雅以及事件驱动IO的可伸缩性(Erlang VM使用了epoll / kqueue)。
更新:这是一些有趣的笔记,当时对我很有影响力。请特别注意锁和回调如何相互影响。
答案 4 :(得分:1)
是和否。
事件驱动的框架通常允许您执行通常需要多个线程和1个线程的事情。这就是为什么它们通常是单线程的。
但是,事件驱动的框架无法将事件分派给多个线程。
答案 5 :(得分:1)
这个经验法则根本不适用于非GUI框架。请参阅威尔士的SEDA架构,请参阅yield(code.google.com/p/yield)以获得良好的python / c ++混合实现。