2011-11-08 10 views
16

Questa è una domanda successiva a Is a successful send() "atomic"?, poiché penso che in realtà riguardi le chiamate di sistema in generale, non solo le mandate sui socket.Quando e come vengono interrotte le chiamate di sistema?

Quali chiamate di sistema possono essere interrotte e quando si trovano, dove viene gestita l'interruzione? Ho imparato a conoscere SA_RESTART, ma non capisco esattamente cosa sta succedendo.

  • Se faccio una chiamata di sistema senza SA_RESTART, può la chiamata essere interrotta da qualsiasi tipo di interrupt (ad esempio, l'input dell'utente), che non riguardano la mia domanda, ma richiede il sistema operativo per interrompere la mia chiamata e fare qualcosa altro? Oppure è solo interrotto da segnali che riguardano direttamente il mio processo (CTRL + C, socket chiuso, ...)?

  • Quando si imposta SA_RESTART, quali sono le semantiche di un send() o qualsiasi altro syscall "lento"? Bloccherà sempre fino a quando tutti i miei dati non saranno trasmessi o il socket non funzionerà, oppure può tornare con un numero inferiore al conteggio nel parametro send()?

  • Dove viene eseguito il riavvio? Il sistema operativo sa che desidero riavviare la chiamata in caso di interruzioni o se qualche segnale viene inviato al mio processo e quindi gestito dal codice della libreria? O devo farlo da solo, ad es. avvolgere la chiamata in un ciclo while e riprovare tutte le volte necessarie?

risposta

9

chiamate di sistema possono essere interrotti da qualsiasi signal, questo include tali segnali come SIGINT (generato da CTRL-C), SIGHUP, ecc

Quando SA_RESTART è impostato, un send() torneranno (con lo conteggio inviato) se sono stati trasmessi dati prima che il segnale sia stato ricevuto, verrà restituito un errore EINTR se è stato impostato un timeout di invio (poiché questi non possono essere riavviati), altrimenti il ​​send() verrà riavviato.

Il riavvio della chiamata di sistema è implementato nel codice di gestione del segnale del kernel. La chiamata di sistema internamente restituisce -ERESTARTSYS al rilevamento di un segnale in attesa (o di un'attesa interrotta da un segnale), che fa sì che il codice di gestione del segnale ripristini il puntatore di istruzioni e i registri pertinenti allo stato prima della chiamata, rendendo la ripetizione di syscall.

+1

Significa solo segnali inviati al mio processo, giusto? In qualche modo ho pensato che QUALSIASI interruzione del kernel che gestiva il mio interrupt (una pressione di un tasto, un movimento del mouse, un interrupt del timer, ...) avrebbe causato il ritorno della mia chiamata e il segnale da inviare. Un interruttore di contesto durante la chiamata di sistema non dovrebbe interferire con il mio processo in alcun modo oltre al tempo, giusto? – lxgr

+1

@lxgr, è corretto, il cambio di contesto non interrompe le chiamate di sistema. –

Problemi correlati