在OS X上,fprintf是否是线程安全的?如果是,这个文档在哪里可以找到?
POSIX线程规范(也称为Pthreads),它符合OS X的要求,要求stdio函数是线程安全的。此外,它还提供了flockfile
和funlockfile
函数,以确保其他线程在FILE *被锁定时无法交错进行I/O。
请参见http://pubs.opengroup.org/onlinepubs/007908799/xsh/threads.html,特别是在标题为“Thread-safety”的部分下。
// artificial test for thread safety of fprintf()
// define FLUSH_BUFFER to get a good picture of what's happening, un-def for a buffer test
// the 'pretty print' (FLUSH_BUFFER) output relies on a mono-spaced font
// a writeable file name on the command line will send output to that file
//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define FLUSH_BUFFER
#define NTHREAD 5
#define ITERATIONS 3
const char DOTS[] = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
FILE *outFile;
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
for (int i=1; i<=ITERATIONS; i++) {
long delay = (NTHREAD-tid) * 100000 + (ITERATIONS-i+1) * 10000;
#ifdef FLUSH_BUFFER
fprintf(outFile, "%*sStart thread %d iteration %d\n", (tid+1)*4, " ", tid, i);
usleep(delay);
fprintf(outFile, "%*sFinish thread %d iteration %d %*.*sw/delay %d\n",
(tid+1)*4, " ", tid, i, (NTHREAD-tid+1)*4, (NTHREAD-tid+1)*4, DOTS, delay);
#else
fprintf(outFile, "Start thread %d iteration %d ", tid, i);
usleep(delay);
fprintf(outFile, "Finish thread %d iteration %d w/delay %d\n", tid, i, delay);
#endif
}
pthread_exit(NULL);
}
int main (int argc, char *argv[]) {
pthread_t threads[NTHREAD];
char errStr[100];
int rc;
long t;
if(argc > 1) {
if(! (outFile = fopen(argv[1], "w"))) {
perror(argv[1]);
exit(1);
}
} else
outFile = stdout;
for(t=0; t<NTHREAD; t++) {
fprintf(outFile, "In main: creating thread %ld\n", t);
if(rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t)) {
sprintf(errStr, "ERROR; pthread_create() returned %d", rc);
perror(errStr);
exit(2);
}
}
pthread_exit(NULL);
}