Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 所有事件驱动框架都应该是单线程的吗?_Multithreading_Oop_Events - Fatal编程技术网

Multithreading 所有事件驱动框架都应该是单线程的吗?

Multithreading 所有事件驱动框架都应该是单线程的吗?,multithreading,oop,events,Multithreading,Oop,Events,认为多线程GUI框架是一个失败的梦想。非GUI框架呢?这个经验法则是否扩展到所有事件驱动的框架 以下是引起我注意的文章中的一段话: 输入事件处理的问题在于,它往往与大多数GUI活动的运行方向相反。一般来说,GUI操作从库抽象堆栈的顶部开始,然后“向下”。我在我的应用程序中操作一个抽象概念,它由一些GUI对象表示,因此我从我的应用程序开始,调用高级GUI抽象,调用低级GUI抽象,调用工具箱的丑陋内脏,然后调用操作系统。相反,输入事件从操作系统层开始,并逐渐“向上”分配到抽象层,直到它们到达我的应用

认为多线程GUI框架是一个失败的梦想。非GUI框架呢?这个经验法则是否扩展到所有事件驱动的框架

以下是引起我注意的文章中的一段话:

输入事件处理的问题在于,它往往与大多数GUI活动的运行方向相反。一般来说,GUI操作从库抽象堆栈的顶部开始,然后“向下”。我在我的应用程序中操作一个抽象概念,它由一些GUI对象表示,因此我从我的应用程序开始,调用高级GUI抽象,调用低级GUI抽象,调用工具箱的丑陋内脏,然后调用操作系统。相反,输入事件从操作系统层开始,并逐渐“向上”分配到抽象层,直到它们到达我的应用程序代码中

现在,由于我们使用的是抽象,我们自然会在每个抽象中分别进行锁定。不幸的是,我们有一个经典的锁排序噩梦:我们有两种不同的活动,它们想要以相反的顺序获取锁。因此,僵局几乎是不可避免的


不。即使是作为经验法则,它也只是简单地说“很难让它们工作。”但事件驱动框架非常类似于事件驱动模拟和其他各种东西;在Javaworld中很难做到这一点并不是因为多线程,而是因为Java中可用的抽象

在另一个环境中,如Erlang,它既非常自然,又非常健壮

更新 听起来他还是有错误的抽象概念。我看不出这个问题中有什么固有的东西会导致锁定问题。我认为,关键在于:

现在,由于我们使用的是抽象概念, 我们自然会进行锁定 分别在每个抽象中。 不幸的是,我们有经典的 锁订购噩梦:我们有两个 正在进行的各种活动 想要在相反的位置获取锁 命令。因此,僵局几乎是不可避免的 不可避免

那么,为什么僵局几乎不可避免?因为有两种不同类型的活动正在进行,它们希望以相反的顺序获取锁。这是因为“我们自然会在每个抽象中分别进行锁定。”

换句话说,他选择了——或者说环境为他选择了——不支持他需求的抽象。因此,他似乎声称,不存在任何抽象概念。我觉得这没有说服力。我首先要检查两件事:

  • “当然,我们将在抽象中单独锁定”,以及
  • “我们正在进行的事件希望以相反的顺序获取锁。”
根据我的经验,“NaturalX”通常意味着“我没有真正寻找其他选项”。我非常怀疑事件是否希望以相反的顺序获得锁;你得到一把锁,你做点什么,然后把它打开

关键是,他似乎提出了这样一个事实:他发现很难提出一个方案,作为一个定理,说没有方案可以工作


如果没有更多关于这个问题的细节,就很难构造一个反例,但是正如我前面所说的,有很多系统的例子,它们的事件从各个方向异步地从内部进程和GUI开始,它们设法拥有许多并发的控制线程,并且不会死锁。之所以想到Erlang,是因为其中一类问题,电话,是Erlang的发明者,事实上,这类问题就是Erlang发明的原因。

我想知道有多少问题来自多线程不适合事件处理的事实,许多构建GUI的开发人员都不精通多线程,这有多大的问题


我倾向于支持后一种情况,也倾向于支持某些框架的大块性。例如,我发现Eclipse中的GUI代码编写起来相当烦人,因为没有更方便的方法来处理繁重的逻辑和GUI代码。

一般来说,是的,因为事件驱动框架类似于Reactor模式,它规定了一个等待事件的主循环(“事件循环”),然后调用各种元素的已注册回调

这就是事件驱动框架的传统定义。 下面是关于Erlang进程如何绑定到VM事件循环的详细描述:

Erlang进程与Erlang VM的事件驱动网络IO核心紧密集成。进程可以“拥有”套接字,并向套接字发送和接收消息。这提供了面向并发编程的优雅性以及事件驱动IO的可扩展性(Erlang VM在幕后使用epoll/kqueue)

更新:这里有一些有趣的注释,在当时对我影响很大。请特别注意锁和回调是如何相互作用的


我不得不说不,但有一个警告。围绕共享状态的事件驱动框架,如UI,应该是单线程的。围绕通知的事件驱动框架,如机械监控(例如,让您知道管道中的压力何时过高),可以是单线程,但可能更适合多线程

当然,构建多线程UI框架是可能的,我自己也这么做了。最后我将其转换为单线程。部分原因确实属于Charlie所说的“太难了”。问题是,在多线程UI框架中,不仅我必须处理线程问题,任何使用UI的人都必须处理线程问题。核心当然是线程安全的,但是任何编写控件的人都必须使该线程安全。尽管如此,在对UI进行多次更改时,您必须