Joh*_*hew 1 c linux thread-safety
这样的代码在linux上是安全的,在某种意义上1)它不会崩溃并且无法读取free()ed内存和2)freopen()ed文件与fclose()ed文件共享相同的lockcount?
线程1:
flockfile(file);
freopen("name", a", file);
funlockfile(file);
Run Code Online (Sandbox Code Playgroud)
线程2:
flockfile(file);
fputs("stuff", file);
funlockfile(file);
Run Code Online (Sandbox Code Playgroud)
关闭时没有安全操作FILE*.来自fclose(3):
...对流的任何进一步访问(包括对fclose()的另一次调用)都会导致未定义的行为.
这是因为fclose(可能)释放文件指针指向的对象.
但是,当freopen锁被绑定到流而不是底层文件时,锁定流是完全安全的.事实上,根据flockfile(3):
stdio函数是线程安全的.
此外,freopen在freopen中也标记为"MT-safe" (3).因此,freopen必须在内部锁定1以避免关闭底层文件描述符,而另一个线程是,例如,freopen它.因此,从外部取出它必须是安全的(锁是可重复的).
最后,您实际上并不需要这些调用,flockfile因为所有文件操作都已经是线程安全的.
1我已经验证(通过阅读源代码)glibc和openbsd的libc(也用于android)在freopen调用时在内部锁定流.
glibc freopen代码打开:
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.
Run Code Online (Sandbox Code Playgroud)
并结束:
_IO_release_lock (fp);
return result;
}
Run Code Online (Sandbox Code Playgroud)