读取和写入相同的文件线程安全吗?

时间:2014-03-13 00:31:07

标签: c multithreading posix

我有一个名为" data.txt"。

的文件

我有两个主题。

第一个帖子,读取文件的全部内容:

while(1){
    char buf[1000];
    FILE* fp = fopen("data.txt","r");
    while(fread(buf,1,1000,fp)>0){
        /* process data */
    }
    fclose(fp);
}

第二个线程将数据附加到文件:

while(1){
    FILE* fp = fopen("data.txt","a");
    fwrite("hello\n",1,6,fp);
    fclose(fp);
}

在这种情况下读取和写入(WHITOUT MUTEX或FILELOCKING)是线程安全吗? (没有分段错误等...)

2 个答案:

答案 0 :(得分:5)

首先,大多数标准库函数,除了显式解锁的I / O函数之外,都是正式的线程安全的。见http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.htmlhttp://pubs.opengroup.org/onlinepubs/009695299/functions/flockfile.html明确指出除特殊要求外不需要flockfile()。

关于解锁函数的一些注意事项非常有趣:

  

当且仅当在调用线程拥有(FILE *)对象时调用它们时,可以安全地在多线程程序中使用这些函数,就像成功调用flockfile()或ftrylockfile之后的情况一样( )功能。

这意味着正常的锁定函数的线程安全保证比你正在做的更强:即使使用相同的FILE指针,它们也是安全的 one fopen()的结果)。很容易看出FILE结构中的簿记信息的并发更新如何破坏它;正常的标准库函数保证不会。

另一方面,C标准说:“同一个文件是否可以同时打开多次也是实现定义的。”有CERT advisory可以避免这种情况。这是一个多个FILE结构的用例,通过两个fopen()调用获得,可能没有介入fclose()到同一个底层物理文件。

标准使得定义此实现可能反映某些操作系统的(潜在)限制。

方面的评论:成功尝试并发算法几次并不能保证它是正确的。并发问题是可怕的野兽,它们以不可预测的方式抬头。< / p>

答案 1 :(得分:3)

fread()fwrite()本质上是线程安全。它们不太可能导致程序崩溃,但无法保证读取和写入的顺序。

如果您打算同时使用它们,则必须使用flockfile()funlockfile()