这样的代码在linux上是安全的,在某种意义上说1)它不会崩溃并且无法读取free()ed内存和2)freopen()ed文件与fclose()ed文件共享相同的lockcount ?
主题1:
flockfile(file);
freopen("name", a", file);
funlockfile(file);
线程2:
flockfile(file);
fputs("stuff", file);
funlockfile(file);
答案 0 :(得分:6)
关闭的FILE*
没有安全操作。来自fclose(3):
...对流的任何进一步访问(包括对fclose()的另一次调用)都会导致未定义的行为。
这是因为fclose
(可能)释放了文件指针所指向的对象。
但是,在freopen
锁定流是非常安全的,因为锁被绑定到流,而不是基础文件。事实上,根据flockfile(3):
stdio函数是线程安全的。
此外,freopen
也标有" MT-safe"在freopen(3)。因此,freopen
必须在内部锁定 1 以避免关闭文件描述符的底层,而另一个线程例如是freopen
。因此,从外部取下它必须是安全的(锁是可重复的)。
最后,您实际上并不需要对flockfile
进行调用,因为所有文件操作都已经是线程安全的。
1 我已经验证(通过阅读源代码)glibc和openbsd的libc(也在android上使用)在freopen
为freopen
时内部锁定流调用。
glibc FILE*
freopen (filename, mode, fp)
const char* filename;
const char* mode;
FILE* fp;
{
FILE *result;
CHECK_FILE (fp, NULL);
if (!(fp->_flags & _IO_IS_FILEBUF))
return NULL;
_IO_acquire_lock (fp); // <-- This a macro that calls the private equivalent of flockfile and does some gcc cleanup magic.
代码打开:
_IO_release_lock (fp);
return result;
}
关闭时间:
int main(void)
{
char x[20];
cout << "enter a C string:";
cin >> x;
cout << x << endl;
return 0;
}