MSVCRT的fprintf()线程的实现安全吗?

sas*_*alm 6 c printf multithreading msvcrt

似乎glibc的fprintf()实现是线程安全的,但对于微软的CRT来说也是如此吗?

通过线程安全,我并不仅仅意味着崩溃,而且如果多个线程(在同一个进程中)调用fprintf(),文本将不会混合.

也就是说,例如,如果线程A调用fprintf(stdout, "aaaa");并且线程B调用fprintf(stdout, "bbbb");它,则保证不会混合成为aabbaabb.

有这样的保证吗?

Jam*_*lis 10

是.在多线程运行时库中,每个流都有一个关联的锁.此锁定是在对printf函数的任何调用开始时获取的,直到printf函数返回之前才会释放.

C11需要此行为(在C11之前,标准C中没有"线程"的概念).C11§7.21.2/ 7-8规定:

每个流都有一个关联的锁,用于在多个执行线程访问流时阻止数据争用,并限制多个线程执行的流操作的交错.一次只有一个线程可以保持此锁定.锁是可重入的:单个线程可以在给定时间多次保持锁.

读取,写入,定位或查询流的位置的所有函数在访问流之前锁定流.当访问完成时,它们释放与流关联的锁.

Visual C++不完全支持C11,但它确实符合此要求.其他一些Visual C++特定的注释:

只要您没有定义_CRT_DISABLE_PERFCRIT_LOCKS(仅适用于静态链接的运行时库,libcmt.lib和朋友)或使用_nolock-suffixed函数,那么单个流上的大多数操作都是原子操作.

如果在流上的多个操作中需要原子性,则可以通过使用_lock_file和自己获取和释放流锁来自行获取文件锁_unlock_file.