【问题标题】:Why the same thread must be used?为什么必须使用相同的线程?
【发布时间】:2015-12-22 09:00:08
【问题描述】:

在各种库中,某些操作必须发生在另一个操作发生在同一个线程上。一些示例包括 Swing EDT 和 OpenGL。

因此,当有人说“您只能在创建 ObjectY 的同一线程上调用 methodX()”或“在调用 methodY 之前,上下文必须首先与 threadX 关联”时......

幕后发生了什么?

它是如何执行的?

为什么会这样?例如为什么即使对象正在进行任何操作,我也不能从另一个线程发送命令?

【问题讨论】:

  • 我猜线程 ID 保存在某个地方,并与当前正在执行的线程 ID 进行比较。如果它不匹配它会抛出一个异常,具有这个的代码可能不是线程安全的,所以它们只是在更糟糕的事情发生之前安全地中断你的程序。
  • 我想这是合理的。我个人不是强制安全的粉丝,但最终这真的不是问题。如果你想回答我会接受。
  • 我觉得回答的不好,我觉得应该有这方面经验的人来回答。

标签: language-agnostic thread-safety


【解决方案1】:

大多数窗口系统对于线程和(直接)操作窗口的代码之间的交互都有相当具体的规则。对于大多数典型情况,这是通过“外部世界”发送消息这一事实相当透明地处理的,处理这些消息并直接操作目标窗口的代码在(一个)右线程中运行。

我猜我们在这里看到了相同限制的表现。不同之处在于 OpenGL 和 Swing EDT 根据函数调用而不是要发送的消息来公开功能。这些函数直接操作底层窗口,典型的窗口系统只需要在正确的线程中发生——因此,您最好只从正确的线程中调用这些函数。

就强制执行而言:至少在我见过的大多数系统中,“强制执行”包括您的应用程序在您做错事时崩溃。如果幸运的话,您可能会从操作系统收到一条很好的有用消息,说明您从错误的线程调用了函数 X(尽管它所引用的函数 X 很可能是您从未从任何线程直接调用过的函数) )。在更常见的情况下,您会收到类似 segmentation fault attempting to write address 0x12345678 的错误,但根本没有任何迹象表明您做错了什么来触发它。

至于为什么这样做:如上所述,它或多或少是由底层窗口系统强制执行的。如果您想更进一步并询问他们为什么要求这样做,我想这主要是简单和速度的问题。要求与窗口的所有直接交互都通过单个线程避免了到处处理并发。添加允许多个线程同时使用它所必需的所有互斥锁(等等)会导致开发速度慢得多,并且(可能)执行速度也会慢很多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2013-01-25
    • 2022-01-26
    • 2015-10-27
    • 2017-01-05
    相关资源
    最近更新 更多