Question

Je travaille sur du code qui ressemble à ceci

... 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;
}

Lorsque le processus est créé, toutes les variables sont également clonées. Dans le cas normal, toutes les copies de var sont libérées.

S'il y a une erreur de fork () , j'envoie le signal SIGTERM à tous les processus créés. Et j’ai besoin d’écrire un gestionnaire de signal pour SIGTERM qui libère la var et termine l’application. Cependant, free () n’est pas une fonction sans danger pour les signaux - je ne devrais donc pas l’appeler. Mais comment libérer () cette variable?

Merci beaucoup pour vos réponses ...

EDIT: valgrind indique également une variable encore accessible:

==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.
Était-ce utile?

La solution

Je doute que vous en ayez besoin. Tout système d’exploitation prenant en charge fork () libérera automatiquement les allocations de malloc () lorsqu’un processus se terminera, quel que soit le processus (y compris la terminaison).

Il existe des environnements dans lesquels les programmes C ne s'exécutent pas dans des processus et dans lesquels vous devez faire très attention à ce que vous laissez traîner à la sortie. Mais ces environnements ne sont pas POSIX et ne prendront pas en charge fork (). Ils pourraient ne pas supporter les signaux, d'ailleurs. Si vous écrivez pour un tel environnement inhabituel, consultez votre documentation ...

Si vous souhaitez voir un rapport clean valgrind, vous pouvez demander au gestionnaire de coller un événement dans la boucle d'événements de l'enfant (ou de définir un indicateur et de publier un sémaphore, ou autre), et de traiter l'événement comme une sortie propre. C’est également ce que vous feriez si votre programme était une application interactive et que vous vouliez sauvegarder les données de l’utilisateur sur un SIGTERM, en supposant que votre infrastructure d’interface utilisateur ne traduise pas déjà SIGTERM en un événement pour vous.

Autres conseils

Je peux mal comprendre quelque chose, mais sûrement après SIGTERM, tout le processus disparaîtra, emportant votre variable avec elle?

Vous pouvez utiliser exec pour démarrer le processus enfant depuis main plutôt que d’appeler directement la fonction child (). Utilisez un argument de ligne de commande pour indiquer au programme enfant d'effectuer le travail dans main. Ensuite, le processus enfant pourra nettoyer correctement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top