【问题标题】:How to define threadsafe?如何定义线程安全?
【发布时间】:2010-01-04 12:00:20
【问题描述】:

Threadsafe 是一个经常出现在文档中的术语,但是很少有人解释它的含义,尤其是第一次学习线程的人可以理解的语言。

那么你如何向刚接触线程的人解释Threadsafe 代码呢? 我对选项的想法是:

  • 你是否使用了一份代码清单 线程安全与线程不安全
  • 书籍定义
  • 一个有用的比喻

【问题讨论】:

    标签: multithreading definition


    【解决方案1】:

    多线程导致非确定性执行 - 您无法确切知道某段并行代码何时运行。

    鉴于此,这个美妙的 multithreading tutorial 定义了 线程安全,如下所示:

    线程安全代码是在任何多线程场景下都没有不确定性的代码。线程安全主要通过锁定来实现,并通过减少线程之间交互的可能性来实现。

    这意味着无论线程如何运行,其行为始终是明确定义的(因此不受 race conditions 影响)。

    【讨论】:

      【解决方案2】:

      Eric Lippert says

      当我被问到“这段代码线程安全吗?”我总是不得不反击并询问“您关心的确切线程场景是什么?”和“在每种情况下对象的正确行为是什么? em>”。

      如果说代码是“线程安全”而不以某种方式传达所使用的线程安全机制可以防止和不防止哪些不良行为,这是无益的。

      【讨论】:

        【解决方案3】:

        生日,

        阅读POSIX paper on thread safety 是一个不错的起点。

        编辑:前几段让您快速了解线程安全和可重入代码。

        HTH

        干杯,

        【讨论】:

          【解决方案4】:

          我可能错了,但线程安全的标准之一是仅使用局部变量。如果从不同线程调用相同的函数,使用全局变量可能会产生未定义的结果。

          【讨论】:

          • 只有部分正确,因为您只需要使用互斥锁保护这些全局变量,例如拥有线程安全函数
          • @claferri:我认为提出这个问题的目的是想知道哪些事情会导致不安全的线程。您绝对可以使用同步对象(不仅仅是互斥体,还有信号量/关键部分等)来确保线程安全。我想指出导致线程不安全代码的原因之一。没有必要投反对票。
          【解决方案5】:

          线程安全函数/对象(以下简称对象)是一种旨在支持多个并发调用的对象。这可以通过并行请求的序列化或对交织调用的某种支持来实现。

          本质上,如果对象安全地支持并发请求(来自多个线程),那么它就是线程安全的。如果它不是线程安全的,多个并发调用可能会破坏其状态。

          考虑一下酒店的日志。如果一个人在书中写作,而另一个人出现并开始同时写他的信息,最终的结果将是两种信息的混合。这也可以通过多个线程写入输出流来证明。

          【讨论】:

            【解决方案6】:

            我想说要了解线程安全,首先要了解线程安全函数和可重入函数之间的区别。

            详情请查看The difference between thread-safety and re-entrancy

            【讨论】:

              【解决方案7】:

              踩踏安全代码是不会因为同一数据同时在两个地方更改而失败的代码。线程安全是一个比并发安全更小的概念,因为它假定它实际上是同一个程序的两个线程,而不是(比如说)硬件修改数据或操作系统。

              【讨论】:

                【解决方案8】:

                该术语的一个特别有价值的方面是它位于并发行为的范围内,其中线程安全是最强的,中断安全是比线程安全更弱的约束,并且可重入甚至更弱。

                在线程安全的情况下,这意味着有问题的代码符合一致的 api 并利用资源,以便不同线程中的其他代码(例如其自身的另一个并发实例)不会导致不一致, 只要它也符合相同的使用模式。必须指定使用模式以实现对线程安全的任何合理预期。

                中断安全约束通常不会出现在现代用户空间代码中,因为操作系统很好地隐藏了这一点,但是,在内核模式下,这非常重要。这意味着代码将成功完成,即使在执行过程中触发了中断。

                最后一个,可重入,几乎可以保证所有现代语言,进出用户空间,它只是意味着一段代码可能会被多次输入,即使在代码执行之前还没有执行旧案例中的部分。例如,这可能发生在递归函数调用的情况下。通过访问不可重入代码中的共享全局状态变量,很容易违反语言提供的可重入性。

                【讨论】:

                • 涉及两个不同的问题——第一个是嵌套的动作实例是否不能在第一个执行过程中的任何时间点开始,或者它是否可能发生在特定的允许点,或者在本质上是任意点;第二个是嵌套动作是否必须在原始动作恢复之前完成。因为多任务处理如此流行,大多数可以启动嵌套动作的例程都允许它与第一个动作并发运行,但它曾经(并且在某些嵌入式上下文中仍然是)常见的嵌套动作来保存上下文第一个……
                • ...进入时,退出时恢复。在使用全局状态的场景中,这种模式可能比拥有多个实时状态以及在它们之间切换的能力更容易使用。但是,它确实对一个人可以执行的多任务类型施加了一些限制。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-08-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-05-01
                • 2012-10-24
                • 1970-01-01
                相关资源
                最近更新 更多