C標準ライブラリの<stdio.h>ヘッダで提供されるストリーム入出力関数において、複数スレッドから同時に対象ストリーム入出力操作を行ったときの振る舞い(スレッド安全性)に関するメモ。
まとめ:
POSIX
POSIXシステムが定める全関数は基本的にスレッド安全(Thread-Safe)であると定義され、C標準ライブラリの関数fgetc
やprintf
などを用いて、異なるスレッドから同時にストリーム入出力操作を行ってもよい。*1
POSIX規格(IEEE Std 1003.1-2008)より "Thread-Safe" の定義、およびflockfile
, funlockfile
関数仕様から一部引用(下線部は強調)。
3.399 Thread-Safe
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_399
A function that may be safely invoked concurrently by multiple threads. Each function defined in the System Interfaces volume of POSIX.1-2008 is thread-safe unless explicitly stated otherwise. Examples are any "pure" function, a function which holds a mutex locked while it is accessing static storage, or objects shared among threads.
SYNOPSIS
#include <stdio.h> void flockfile(FILE *file); int ftrylockfile(FILE *file); void funlockfile(FILE *file);DESCRIPTION
http://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html
These functions shall provide for explicit application-level locking of stdio (FILE *
) objects. These functions can be used by a thread to delineate a sequence of I/O statements that are executed as a unit.
(snip)
All functions that reference (FILE *
) objects shall behave as if they use flockfile() and funlockfile() internally to obtain ownership of these (FILE *
) objects.
C11
C11標準ライブラリにおけるストリーム入出力操作のスレッド安全性に関しては、POSIXシステムと同様の定義がなされている。ただしPOSIXとは異なり、アプリケーションコードから明示的にストリーム関連ロックを操作する関数は提供されない。
N1570 7.21.2/p7-8より引用。
7 Each stream has an associated lock that is used to prevent data races when multiple threads of execution access a stream, and to restrict the interleaving of stream operations performed by multiple threads. Only one thread may hold this lock at a time. The lock is reentrant: a single thread may hold the lock multiple times at a given time.
8 All functions that read, write, position, or query the position of a stream lock the stream before accessing it. They release the lock associated with the stream when the access is complete.
関連URL