我有一个名为" 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)是线程安全吗? (没有分段错误等...)
答案 0 :(得分:5)
首先,大多数标准库函数,除了显式解锁的I / O函数之外,都是正式的线程安全的。见http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html。 http://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()
。