Столкнулся с проблемой пропадания строк при многопоточной записи в STDOUT_FILENO (т.е. write(), не fwrite()).
Нашёл в интернете одну прошлогоднюю программу с описанием подобной проблемы и слегка её подпилил:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <inttypes.h>
#define NTHREADS 10
volatile int flag = 0;
void *start(void *arg) {
    char msg[255];
    int res;
    snprintf(msg, sizeof(msg), "hi from %"PRIxPTR"\n", (uintptr_t)arg);
    if ((uintptr_t)arg == NTHREADS - 1)
        flag = 1;
    while (!flag) ; /* thread barrier */
#if 1
    res = write(STDOUT_FILENO,msg,strlen(msg));
    if (res != strlen(msg))
        fprintf(stderr,"Failure: %i %s\n",res,strerror(res));
#else
    fputs(msg,stdout);
#endif
#if 1 /* work extra hard to flush output (makes no difference) */
    fflush(NULL);
    fsync(STDOUT_FILENO);
    sync();
#endif
    return NULL;
}
int main() {
    uintptr_t i;
    pthread_t id[NTHREADS];
    for (i =0 ; i < sizeof(id) / sizeof(id[0]); i++) {
        int ret = pthread_create(&(id[i]),NULL,&start,(void *)i);
        if (ret)
            fprintf(stderr, "pthread_create: %s\n", strerror(ret));
    }
    for (i =0 ; i < sizeof(id) / sizeof(id[0]); i++) {
        pthread_join(id[i], NULL);
    }
    return 0;
}
Компилируем:
$ gcc -Wall tmp.c -lpthread
Запускаем:
$ ./a.out | wc -l 10
Кажется, что всё нормально, но перенаправим вывод в файл, и начнутся чудеса:
$ ./a.out >o && wc -l o 2 o $ ./a.out >o && wc -l o 2 o $ ./a.out >o && wc -l o 4 o $ ./a.out >o && wc -l o 3 o $ ./a.out >o && wc -l o 3 o $ ./a.out >o && wc -l o 2 o $ ./a.out >o && wc -l o 3 o
Но если перенаправлять в существующий файл (дописыванием в конец):
$ rm o && touch o && ./a.out >> o && wc -l o 10 o $ rm o && touch o && ./a.out >> o && wc -l o 10 o $ rm o && touch o && ./a.out >> o && wc -l o 10 o
ОС - убунта 11.4. Под рукой есть солярка, на ней проблема не наблюдается. Объясните, пожалуйста, в чём может быть проблема?
