An additional problem occurs with standard I/O. Programmers are accustomed to routines, such as getc(3C) and putc(3C) , that are implemented as macros, being very quick. Because of the speed of getc(3C) and putc(3C), these macros can be used within the inner loop of a program with no concerns about efficiency.
However, when getc(3C) and putc(3C) are made thread safe the macros suddenly become more expensive. The macros now require at least two internal subroutine calls, to lock and unlock a mutex.
getc_unlocked(3C) and putc_unlocked(3C) do not acquire locks on a mutex. These getc_unlocked() or putc_unlocked() macros are as quick as the original, nonthread-safe versions of getc(3C) and putc(3C).
However, to use these macros in a thread-safe way, you must explicitly lock and release the mutexes that protect the standard I/O streams, using flockfile(3C) and funlockfile(3C). The calls to these latter routines are placed outside the loop. Calls to getc_unlocked() or putc_unlocked() are placed inside the loop.