Domanda

Lavoro sul codice qualcosa del genere

... HEADERS ...

int *var;

void child() {
  ... //some work
  free(var);
  exit(EXIT_SUCCESSFUL);
}

int main(void) {
  ...
  //allocate variable
  var = (int *) malloc(N*sizeof(int));
  ... //work with var

  for(int i; i<PROC_COUNT; i++) {
    pid_t child = fork();
    if(pid == 0) {
      child(); //main function of new proces
      break;
    }
    elseif(pid < 0) {
      //there is enormous problem -> kill every proces
      kill(0, SIGTERM);
      waitpid(0, NULL, 0); //wait for children
      free(var);
      exit(EXIT_FAILURE);
    }

  }
  free(var);
  return EXIT_SUCCESS;
}

Quando il processo viene biforcato, vengono clonate anche tutte le variabili. Nel caso normale tutte le copie di var vengono liberate.

Se si verifica un errore di fork () , invio il segnale SIGTERM a tutti i processi creati. E devo scrivere il gestore del segnale per SIGTERM che libera var e termina l'applicazione. Tuttavia, free () non è funzione di sicurezza del segnale - quindi non dovrei chiamarlo. Ma come liberare () quella variabile?

Mille grazie per le tue risposte ...

EDIT: valgrind mostra anche una variabile ancora raggiungibile:

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks.
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated.
==5928== For counts of detected errors, rerun with: -v
==5928== searching for pointers to 1 not-freed blocks.
==5928== checked 49,164 bytes.
È stato utile?

Soluzione

Dubito che tu debba farlo. Qualsiasi sistema operativo che supporti fork (), libererà automaticamente anche le allocazioni da malloc () all'uscita da un processo, indipendentemente da come lo fa (inclusa la terminazione).

Esistono ambienti in cui i programmi C non vengono eseguiti nei processi e in cui devi stare molto attento a ciò che lasci in giro all'uscita. Ma quegli ambienti non sono POSIX e non supporteranno fork (). Potrebbero non supportare i segnali, del resto. Se stai scrivendo per un ambiente così insolito, controlla la tua documentazione ...

Se si desidera visualizzare un rapporto valgrind pulito, è possibile fare in modo che il gestore inserisca un evento nel loop degli eventi del bambino (o impostare un flag e pubblicare un semaforo o altro) ed elaborare l'evento come un'uscita pulita. Questo è anche ciò che faresti se il tuo programma fosse un'applicazione interattiva e volessi salvare i dati dell'utente su un SIGTERM, supponendo che il tuo framework UI non abbia già tradotto SIGTERM in un evento per te.

Altri suggerimenti

Potrei fraintendere qualcosa, ma sicuramente dopo SIGTERM l'intero processo scomparirà, portando con te la tua variabile?

È possibile utilizzare exec per avviare il processo figlio da main anziché chiamare direttamente la funzione child (). Utilizzare un argomento della riga di comando per notificare al programma figlio di eseguire il lavoro in main. Quindi il processo figlio sarà in grado di pulire correttamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top