用于IO操作的单个“锁定”或单独的读取器/写入器锁定?

时间:2012-04-24 05:17:21

标签: c# .net multithreading performance

我有几个线程在编写和阅读不同的文件。

对于所有磁盘操作,是否可以使用单个锁{}(所有受保护区域的相同变量)?所以我没有两个线程同时读取和写入磁盘来寻找?

我还听说我也可以在线程上用于读取而另一个用于写入,这总是如此吗?为什么呢?

4 个答案:

答案 0 :(得分:2)

如果每个线程读取或写入不同的文件,我不明白为什么需要并发。

通常,有多个线程访问同一个文件(资源)进行读写。 在那种情况下,当一个线程正在写入该文件时,所有其他线程都必须等待。 这是一个称为“读者 - 作家”的经典并发问题。

您可以在此处找到更多信息: http://en.wikipedia.org/wiki/Readers-writers_problem

答案 1 :(得分:1)

如果您没有从任何线程访问其他线程的代码,那么一个用于同步的对象就足够了,但它会增加等待资源的线程队列。每个资源或资源组的一个同步对象将是更好的选项

答案 2 :(得分:0)

仅使用一个锁可能会降低您的应用程序速度。如果一个线程正在写一个文件很长一段时间,也许应该允许其他线程读取其他一些文件。 你能更精确地了解哪些线程访问哪些文件?

答案 3 :(得分:0)

您的要求似乎有点混乱和变形。一条评论说“线程正在写入同一个文件”而另一条评论说“所有文件同时写入同一文件集合”。

有一些选择:

1)用一个锁锁定读写。这是最简单的方法,但调用线程之间的争用概率最高,因为锁定在磁盘操作期间保持不变。

2)每个文件使用一个读取器/写入器锁定锁定读取和写入 - 这比(1)更好,因为不会发生不同文件的内容。对同一文件的读/写之间仍可能存在争用。

2)排队读取/写入一个写入器线程。这往往会更多地运用磁盘,因为它必须在文件之间进行交换,因为它会出列并执行写入请求,但最大限度地减少了调用线程中的写入争用 - 它们只需要锁定队列一段时间来推送指针。读取变得很慢,因为调用线程必须等待同步对象,直到它们的读取请求完成。写入时争用率低,但所有读取的延迟都很高。

3)与(2)类似,但每个文件使用一个线程。如果输出文件分布在多个物理磁盘上,这对于几个文件来说可能会花费很多内存,并且只能真正帮助(2)。像(2)一样,低争用和慢读。

4)将写入作为线程池任务排队。我不确定如何准确地执行此操作 - 文件上下文必须作为参数传递,对它的访问可能需要锁定 - 这可能无法有效地工作。像(2)一样,低争用和慢读。

5)重新设计您的应用以完全避免此要求?