Как освободить динамическую выделяемую переменную с помощью SIGTERM?

StackOverflow https://stackoverflow.com/questions/815439

  •  03-07-2019
  •  | 
  •  

Вопрос

Я работаю над кодом примерно так

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

Когда процесс разветвляется, все переменные также клонируются.В обычном случае все копии var освобождаются.

Если есть ошибка с помощью fork(), я посылаю сигнал SIGTERM всем созданным процессам.И мне нужно написать обработчик сигнала для SIGTERM, который освобождает var и завершает работу приложения.Однако free() не является signal safe function -- так что мне не следует это называть.Но как освободить () эту переменную?

Большое спасибо за ваши ответы...

Редактировать:valgrind также показывает все еще достижимую переменную:

==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.
Это было полезно?

Решение

Я сомневаюсь, что вам нужно. Любая ОС, которая поддерживает fork (), также автоматически освобождает выделения из malloc () при выходе из процесса, независимо от того, как он это делает (включая завершение).

Существуют среды, в которых программы на C не запускаются в процессах, и где вы должны быть очень осторожны, чтобы не выходить из процесса при выходе. Но эти среды не POSIX и не будут поддерживать fork (). Они могут не поддерживать сигналы, в этом отношении. Если вы пишете для любой такой необычной среды, проверьте документацию ...

Если вы хотите увидеть чистый отчет valgrind, вы можете сделать так, чтобы обработчик вставлял событие в дочерний цикл событий (или устанавливал флаг и отправлял семафор или что-то еще) и обрабатывал событие как чистый выход. Это также то, что вы сделали бы, если бы ваша программа была интерактивным приложением, и вы хотели сохранить данные пользователя на SIGTERM, предполагая, что ваша структура пользовательского интерфейса еще не преобразовала SIGTERM в событие для вас.

Другие советы

Возможно, я что-то недопонимаю, но наверняка после SIGTERM весь процесс исчезнет, забрав с собой вашу переменную?

Вы можете использовать exec для запуска дочернего процесса из main вместо непосредственного вызова функции child (). Используйте аргумент командной строки, чтобы уведомить дочернюю программу о выполнении работы в main. Тогда дочерний процесс сможет правильно очистить.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top