Invia stdout o stderr a un nuovo thread

3

Per problemi di prestazioni, voglio che il log sia inviato a una nuova discussione.

Mentre il programma principale può funzionare, il nuovo thread può scrivere l'errore o altri messaggi su un file senza effetto sul programma principale. Come posso inviare tutto lo stdout al nuovo thread?

Lavoro da fare:

  • crea una nuova discussione, ok
  • apri un file, ok
  • crea una pipe all'interno del thread, ok
  • invia stdout al nuovo thread, con freopen o dup?

Ogni volta che il buffer si riempie o ogni 5 secondi il file di registro riceve nuovi dati.

Poiché è un programma MPI , non posso biforcare l'intero programma. Deve essere un thread Posix.

    
posta Thor 18.04.2013 - 21:00
fonte

2 risposte

6

crea un produttore / consumatore interno

la tua chiamata di registro produrrà un messaggio che verrà consumato dall'altro thread e scritto nel file di registro

dovrai modificare la chiamata al registro per passare alla coda invece di scrivere su stdout ma se hai utilizzato una macro dall'inizio non dovrebbe essere un problema;)

modifica cosa intendo usando una macro per la registrazione è

#define LOG(s,...) printf(s,_VA_ARGS_)

questo cambierebbe in

#define LOG(s,...) do{char[] buff = new char[512]; \
          snprintf(buff,512,s,_VA_ARGS_); \
          pushToLogger(buff);}while(0)

pushToLogger(char*) è la funzione che fa la spinta (e diventa responsabile per free ing buff )

    
risposta data 18.04.2013 - 21:30
fonte
0

Funzionano come previsto, ma c'è molto lavoro. A cosa stai pensando? Queste sono le strutture per la mia lista.

typedef struct logger {
    struct timeval *time1;
    char message[255];
    struct logger *next;
} Logger;

typedef struct queue {
    struct logger *front;
    struct logger *rear;
} Queue;

All'interno della coda c'è la lista collegata. Con la funzione seguente, l'elenco collegato è pieno di messaggi.

void addLogStruct(char* dummyMessage) {
    Logger *tmpLogger = malloc(sizeof(Logger));
    if (queue1.front == NULL ) {
        // first round initialice
        strncpy(logger1.message,
                "*** Laufzeitsystem ***",
                sizeof(logger1.message));
        static struct timeval tmpTime;
        gettimeofday(&tmpTime, NULL );
        logger1.time1 = &tmpTime;
        logger1.next = NULL;
        runLogger = &logger1;
        queue1.front = &logger1;
        queue1.rear = &logger1;
    } else {
        strncpy(tmpLogger->message, dummyMessage, sizeof(tmpLogger->message));
        static struct timeval tmpTime;
        gettimeofday(&tmpTime, NULL );
        tmpLogger->time1 = &tmpTime;
        tmpLogger->next = NULL;
        runLogger->next = tmpLogger;
        queue1.rear = tmpLogger;
        runLogger = runLogger->next;
    }
}

Nella funzione principale ho avviato un thread Posix distaccato. Il seguente metodo viene eseguito ogni 0,05 secondi per controllare l'elenco, se c'è un nuovo messaggio. Se ce n'è uno, verrà scritto sul disco.

int messageQueueThread(void *dummy) {
    Queue *tmpQueue = malloc(sizeof(Queue));
    tmpQueue = (Queue*) dummy;
    Logger *runLog = malloc(sizeof(Logger));
    int must_stop = 0;
    do {
        if (tmpQueue->front != runLog) {
            // Create String for transfer to function
            char tmpString[255];
            char *tmpString2 = timeval2String(tmpQueue->front->time1);
            sprintf(tmpString, "%s %s.\n", tmpString2,
                    tmpQueue->front->message);
            // write message to disk
            writeMessageFile(tmpString);

            // another one
            runLog = tmpQueue->front;

            // reorder logger struct
            if (tmpQueue->front->next != NULL ) {
                tmpQueue->front = tmpQueue->front->next;
            }
            // delete old log message?
        } else {
            // reorder logger struct
            if (tmpQueue->front->next != NULL ) {
                tmpQueue->front = tmpQueue->front->next;
            }
        }
    } while (!busyWait(must_stop));
    return 0;
}

Non è perfetto. Ma funziona più o meno. Lo voglio più semplice, ma non ce la faccio.

    
risposta data 20.04.2013 - 17:15
fonte

Leggi altre domande sui tag