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

时间:2014-03-20 16:28:41

标签: c multithreading printf msvcrt

似乎是glibc's implementation of fprintf() is thread-safe,但对于微软的CRT来说也是这样吗?

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

也就是说,例如,如果主题A调用fprintf(stdout, "aaaa");而主题B调用fprintf(stdout, "bbbb");,则保证不会混合成aabbaabb

有这样的保证吗?

1 个答案:

答案 0 :(得分:10)

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

C11需要此行为(在C11之前,标准C中没有“线程”的概念)。 C11§7.21.2/ 7-8指出:

  

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

     

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

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

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

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