2013-07-10 16 views
6

Ho un processo server multithread, scritto in C/C++ che sto cercando di creare un profilo con perftools di Google. Tuttavia quando eseguo il processo con perftools, molto presto il mio server si ferma con un errore "syscall interrupted", che penso sia causato dal SIGPROF in arrivo. (La chiamata di sistema effettivo che viene interrotta è profondo dentro la mia chiamata a zmq_recv, ma non credo che sia molto importante quale sia.)SIGPROF uccide il mio server quando si utilizza google perftools

È questo il comportamento previsto? Dovrei trattare esplicitamente questo caso in qualche modo? O c'è qualcosa che non va qui?

risposta

8

Dalla documentazione zeroMQ per zmq_recv() ci si può aspettare per tornare EINTR se un segnale viene ricevuto quando è in corso.

Generazione di segnali nel mezzo della zmq_recv() la chiamata sarebbe un compito difficile per qualsiasi test. Fortunatamente gperftools generando una tonnellata di SIGPROF s ha scoperto questo sottile "bug" nel codice.

Questo must essere gestiti in grazia il codice il quadro zeroMQ è grazia cedere il controllo. La logica di tentativi potrebbe essere semplice come modificare la chiamata in corso:

/* Block until a message is available to be received from socket */ 
    rc = zmq_recv (socket, &part, 0); 

con quello nuovo (con la logica di tentativi) come segue:

/* Block until a message is available to be received from socket 
    * Keep retrying if interrupted by any signal 
    */ 
    rc = 0; 
    while(rc != EINTR) { 
     rc = zmq_recv (socket, &part, 0); 
    } 

anche install a signal handler function nel programma. Si può semplicemente ignorare l'interruzione a causa di SIGPROF e continuare a riprovare.

Infine, potresti voler gestire segnali specifici e agire di conseguenza. Ad esempio, terminando con grazia il tuo programma anche se l'utente preme CTRL + C mentre il tuo programma è in attesa su zmq_recv().

/* Block until a message is available to be received from socket 
    * If interrupted by any signal, 
    * - in handler-code: Check for signal number and update status accordingly. 
    * - in regular-code: Check for status and retry/exit as appropriate 
    */ 
    rc = 0; 
    while(rc != EINTR && status == RETRY) { 
     rc = zmq_recv (socket, &part, 0); 
    } 

Nell'interesse di mantenere il codice "pulito", sarà meglio serviti utilizzando questo frammento di codice per scrivere il proprio static inline funzione wrapper intorno zmq_recv() che si può chiamare nel vostro programma.

Per quanto riguarda la decisione di fare zmq_recv() ritorno EINTR alla ricezione dei segnali, si potrebbe desiderare di checkout questo articolo che parla del worse is better philosophy dietro un tale progetto, che è più semplice da un punto di vista dell'attuazione.


UPDATE: codice documentata di gestire segnali nel contesto zmq_recv() è disponibile a git.lucina.net/zeromq-examples.git/tree/zmq-camera.c. È sulla stessa falsariga di quanto spiegato in precedenza, ma sembra ben collaudato e pronto per l'uso con commenti dettagliati sparsi ovunque (yayyy zeromq!).