【问题标题】:Thread Safety of Stream.Write methodStream.Write 方法的线程安全
【发布时间】:2011-07-27 12:54:07
【问题描述】:

MSDN 文档说 Stream 类的实例方法(包括 Stream.Write)不能保证是线程安全的,但这是什么意思?如果一个线程在其他线程尚未从同一对象的同一方法返回之前尝试在 Stream 对象上调用 Stream.Write 会发生什么?会抛出异常,还是对象会按照线程的顺序排队发送数据?有人说可以在没有锁定机制的情况下调用。有人可以澄清一下吗?

【问题讨论】:

    标签: .net stream


    【解决方案1】:

    这意味着你不应该同时从不同的线程对同一个 Stream 实例调用 Read 和 Write 等实例方法。你会得到意想不到的行为。在某些情况下可能会引发异常,在其他情况下您的数据可能已损坏,而在其他情况下它甚至可能会正常工作(如果您足够幸运的话)。

    如果您打算从多个线程中使用这些共享资源,则需要始终使用适当的锁定机制来同步对这些共享资源的访问。

    【讨论】:

    • 我们能否将其推广到所有实例方法,这样如果我们将对对象的非静态方法进行多线程调用,或者只有共享资源(例如网络流或文件访问?很高兴从尝试并经历过这些事情的人那里得到答案(可以肯定),因为我也知道最好始终使用锁定机制。谢谢
    • @Alp:可以创建一个类,使其完全在内部正确同步,因此是线程安全的。对于这样的类,不,您不需要使用外部锁定。对于大多数用例,尽管在外部实现锁定要简单得多,并且在大多数情况下需要正确操作(例如,在对 List<T> 元素的读取和写入之间锁定以确保原子性)。 Read/Write 也可能在内部同步,但不能保证读取/写入所有给定的数据,因此整个操作仍然需要外部锁定。
    • @Alp Hancioglu,不,我们不能一概而论。这就是为什么所有 .NET Framework 方法都被记录在案并且通常应该明确说明它们是否设计为线程安全的。
    • 我认为答案中某处缺少“同时”。只要一次有一个线程,多线程几乎从来都不是问题
    • @Matthew 在一般情况下,内部锁定本身并不能提供安全性。这尤其适用于流,因为您无法预测 Read 是否会读取您需要的所有数据,并且您真的不希望另一个线程窃取“您的”数据的后半部分。因此,您需要锁定一个操作,这几乎总是不止一个方法调用。寻求是另一个例子;如果你寻求然后写,你不知道是否有另一个线程或在你面前踩过东西。
    【解决方案2】:

    Write 是抽象方法,这意味着该方法的行为在 Stream 的子类中定义。 Stream 的一些子类可以提供线程安全的 Write 方法,而另一些则不能。所以你不能说如果你同时从不同的线程调用它的 Write 方法,Stream 的行为会如何,除非你知道你正在处理什么特定的 Thread 子类。

    所以在处理 Stream 对象时应该使用锁定,因为 MSDN 说 Stream 的方法不能保证是线程安全的,因此可能存在并发调用时可能会中断的 Stream。

    但如果您明确使用特定 Stream 的子类,并且您知道它是线程安全的,则无需锁定。

    【讨论】:

      猜你喜欢
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 2013-12-16
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      相关资源
      最近更新 更多