2010-09-09 349 views
1

如果我在不同的线程中多次打开同一文件(.txt文件),则返回的文件描述符将会不同。如果我试图使用文件描述符写入(),写入函数的任何机会都会被阻塞,因为当多个线程试图写入同一个文件时?Linux open()文件描述符

我担心的是当一个线程调用写入单个文件,另一个线程调用写入同一个文件时。那么第二个线程的写入会等待第一个线程的写入先完成吗?如果是这种情况,我如何确保第二次写入的调用不会等待,并且如果有第一次写入就会立即返回,因为我不希望第二个线程的写入等待。

感谢

+3

为什么不先试试? – Rahul 2010-09-09 05:13:59

+0

是的..我写了代码..这个问题是我怎么知道写功能被阻止?有关我如何测试的建议? – Leslieg 2010-09-09 05:17:16

+0

Linux中没有任何东西可以锁定已经打开的文件。就像拉胡尔说的那样,试试看看会发生什么。 – xnine 2010-09-09 05:18:16

回答

3

没有,但是如果他们正在写重叠文件的地区最新的write()总是撞早些时候写道。

一个更常见的问题是关于写入的文件偏移量,这可能是您的真实问题。在这种情况下,答案是:如果您从每个线程调用open(),则不是。写入将发生在从最后的write()剩余的文件偏移量到源自相同原始open()调用的任何描述符,例如由dup()获取的那些描述符,或者由同一进程中的线程共享。

+0

我可以总结你的上面的句子,如果我只打一个电话打开()并获得文件描述符,写入将追加到最后,因此导致它阻止。如果我打开多个调用并获取不同的文件描述符,它将不会被阻塞,但可能会覆盖? – Leslieg 2010-09-09 05:38:57

+0

在您提供的条件下,它不会以任何方式阻止,锁定或同步。 – 2010-09-09 11:19:40

0

您可以在写入模式下打开文件(在这种情况下,写入可以互相打开),也可以以追加模式打开(在这种情况下,操作系统将锁定并确保每次写入都以原子方式完成,从任何线程 - 直接到文件的新结尾)。

所以,使用追加模式。你的线程会快速将数据转移到内核队列中(假设你正在刷新),然后继续处理事情。如果你发现这个速度还不够快,那么你可以尝试将数据从单个线程转移到一个专门用于文件更新的线程中,但首先使用更简单,更清晰的实现,然后使用配置文件来获得工作系统。

1

如果你有多个线程共享相同的资源(在你的情况下,一个文件),你有责任使用某种类型的同步(例如,信号量或互斥锁)来确保只有一个写入正在进行任何时候。否则,结果将不确定。 Unix不会为你记录这一点 - 如果你在一个线程中开始写入,而在另一个线程中写入同一个文件,则不会发生阻塞。写入操作将立即完成,不保证对基础物理设备的I/O操作的顺序 - 它们甚至可以交错。

1

无论你是否使用进程或线程,同时写入同一个文件很可能会导致问题,除非它非常小心。

文件描述符是否相同也没关系。

write()在写入光盘文件时通常不会阻塞,因为更改只会进入OS缓存。这并不重要,有多少任务正在做这件事。

但是,如果您从多个进程写入文件,则可能最终会在文件中产生垃圾,因为写入的顺序不确定。


如果你想写不同部分在多线程同一文件的,那么你可以使用PWRITE()写入到文件中的特定位置,并且多个线程可以共享相同的文件描述。如果你的线程做的是正确的话,这没关系。

这种技术通常不适用于文本文件。文本文件通常只需一次写入一个线程即可获得可预测的内容。