Filetto di fprintf è sicuro su OS X? Se sì, dove è documentato?Filetto di fprintf è sicuro su OS X?
risposta
Questa era una buona domanda, anche se domande simili sono state poste qui molte volte. Ero interessato all'aspetto OSX perché cercavo di mettermi al corrente su quel sistema da solo. (forse dovresti aggiungere il tag OSX)
I THINK fprintf() è thread-safe su OSX. La mia prima ragione è che il popolo di Darwin andava in quella direzione, come dimostra la sua scelta di abbandonare l'errno globale della vecchia scuola a favore della funzione errno(). Per la documentazione, basta seguire "/usr/include/errno.h". Senza quello, nessuna delle cose di libc sarebbe thread-safe. Tuttavia l'uso della funzione errno() non prova nulla su fprintf(). È solo l'inizio. Sono sicuro che tutti conoscono almeno una situazione in cui Apple non ha portato avanti con una buona idea.
Un altro motivo per cui credo nella 'thread-safety' di fprintf() è lo source code, che dovrebbe essere "la cosa reale", almeno fino al 10.6 quando Apple ha chiuso (parte/tutto) di OSX. Esegui la scansione di quel codice per "MT-Safe" e vedrai un CLAIM che la versione non locale di "vfprintf()" è sicura da thread. Di nuovo, questo non prova nulla. Eppure è una forma di documentazione, che volevi.
La mia ultima ragione per credere che fprintf() sia thread-safe è stato un caso di test. Questo non prova molto neanche di niente. Forse dimostra che lo spazio del buffer è thread-safe. OK, era una scusa per scrivere un piccolo programma per divertimento. In realtà, non l'ho scritto. Ho trovato uno scheletro online e l'ho modificato. La definizione "FLUSH_BUFFER" ti consente di vedere più chiaramente cosa sta succedendo. Se quella macro non è definita, si ottiene il test del buffer 'sort-of' (stesso testo senza alcuni terminatori di riga). Non riuscivo a capire un modo per organizzare una collisione più significativa dei fili.
Immagino che potresti scrivere su più file. Scrivere su un singolo file è probabilmente un test migliore. Il programma allegato non è un test definitivo. Sebbene possa essere esteso, non sono sicuro che qualsiasi programma possa essere davvero definitivo. Bottom line: forse dovresti semplicemente MUTEX le tue chiamate a fprintf().
// 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);
}
Il POSIX thread specifica (alias Pthread), che OS X conforme a, richiede che le funzioni stdio sono sicuri thread. Fornisce inoltre le funzioni flockfile
e funlockfile
per garantire che altri thread non possano intercalare I/O su un FILE * mentre è bloccato.
Vedere http://pubs.opengroup.org/onlinepubs/007908799/xsh/threads.html, in particolare nella sezione "Filo-sicurezza".
- 1. Filetto NSUserDefault è sicuro?
- 2. Filetto NSFileManager è sicuro?
- 3. sem_init su OS X
- 4. xlocale rotto su OS X?
- 5. emacs su OS X 10.6
- 6. Mouse multipli su OS X
- 7. HsOpenSSL segfaults su OS X
- 8. PyCharm - $ PATH su OS X
- 9. JNotify su Mac OS X?
- 10. Installa pip su OS X
- 11. Installazione di librerie C++ su OS X
- 12. Installazione di Git su OS X
- 13. Installazione di meld su OS X
- 14. Equivalente di user32.dll su OS X
- 15. Installazione di readline 6.0 su OS X
- 16. installazione di openssl su OS X
- 17. Installazione di GCC 4.7.1 su OS X
- 18. Impostazione SDL su OS X 10.8
- 19. Flask ImportError con bson su OS X
- 20. Installare libpq-dev su Mac OS X
- 21. grep -f su OS X produce segfault
- 22. È possibile eseguire un'applicazione C#/WPF su Mac OS X?
- 23. Dove è il mio file .emacs su Mac OS X
- 24. non è possibile caricare estensioni PHP su OS X Mavericks
- 25. Rileva quando un volume è montato su OS X
- 26. È possibile creare FreeGLUT su Mac OS X?
- 27. non è possibile installare scipy su mac OS X
- 28. Come installare mod_jk su Mac OS X
- 29. Imparare ASP.NET MVC su Mac OS X
- 30. Architettura dell'applicazione Cocoa su Mac OS X