Вызвать функцию, когда программа завершится с помощью ctrl c

Я работаю в среде Linux, и у меня есть программа на C++, и я хочу, чтобы когда я отменял программу с помощью ctrl + c, я хотел бы, чтобы программа выполняла функцию, чтобы закрыть некоторые файлы и напечатать некоторые файлы, есть ли какие-то способ сделать это ?. Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
8 488
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Краткий ответ: изучите функцию signal, в частности, улавливание SIGINT. Вы пишете функцию обратного вызова и передаете ее системе через функцию сигнала, а затем, когда происходит этот конкретный сигнал, система вызывает вашу функцию обратного вызова. Вы можете закрыть файлы и сделать там все, что захотите.

Намного лучше использовать sigaction ().

Jonathan Leffler 15.12.2008 19:48

Вы должны поймать СИГНАЛ. Что-то вроде этого:

void sigint_handler(int sig)
{
    [do some cleanup]
    signal(SIGINT, SIG_DFL);
    kill(getpid(), SIGINT);
}

загружает более подробную информацию здесь

Намного лучше использовать sigaction ().

Jonathan Leffler 15.12.2008 19:47

Джонатан, пожалуйста, расширите это утверждение.

Alnitak 15.12.2008 20:43

ответ выше расширяет его (stackoverflow.com/questions/368927/…)

Colin Pickard 30.01.2009 14:56

Для полноценного рабочего примера вы можете попробовать следующий код:

#include <signal.h>
#include <stdio.h>
#include <stdbool.h>

volatile bool STOP = false;
void sigint_handler(int sig);

int main() {
    signal(SIGINT, sigint_handler);
    while(true) {
        if (STOP) {
            break;
        }
    }
    return 0;
}

void sigint_handler(int sig) {
    printf("\nCTRL-C detected\n");
    STOP = true;
}

Пример выполнения:

[user@host]$ ./a.out 
^C
CTRL-C detected

STOP следует объявить изменчивым, иначе компилятор может произвести некоторую (некорректную) оптимизацию.

Adam Rosenfield 18.12.2008 00:18

Я не специалист по C++, поэтому верю вам на слово и обновлю образец кода :-)

Jay 22.12.2008 10:30

Технически это тоже должен быть sig_atomic_t. POSIX позволяет вам делать больше в обработчике сигналов, чем ISO C. Также вам следует использовать sigaction (). Помимо прочего, если пользователь использует программу для быстрой генерации двух прерываний, ваша программа может умереть с использованием signal () вместо sigaction ().

Jonathan Leffler 22.12.2008 11:12

Обратите внимание на людей, которые могут наткнуться на этот вопрос, вместо этого ища ответ в Окна:

Используйте вызов API SetConsoleCtrlHandler, чтобы установить собственный обработчик и следить за CTRL_C_EVENT, CTRL_BREAK_EVENT или CTRL_CLOSE_EVENT.

Ответ принят как подходящий

signal() может быть опасен в некоторых операционных системах и не рекомендуется в Linux в пользу sigaction(). "сигнал против подписи"

Вот пример, с которым я недавно столкнулся ("Коснитесь сигнала прерывания") и который изменил, когда играл с ним.

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>

struct sigaction old_action;

void sigint_handler(int sig_no)
{
    printf("CTRL-C pressed\n");
    sigaction(SIGINT, &old_action, NULL);
    kill(0, SIGINT);
}

int main()
{

    struct sigaction action;
    memset(&action, 0, sizeof(action));
    action.sa_handler = &sigint_handler;
    sigaction(SIGINT, &action, &old_action);

    pause();

    return 0;
}

Действия в sigint_handler () после printf () нечетные - почему? Кроме того, вы должны pause () вместо цикла while. Инициализация для нового действия тоже не идеальна. Это, вероятно, работает, но это немного рассеянный подход «будем надеяться, что все нули в порядке».

Jonathan Leffler 22.12.2008 11:15

Я обновил его, чтобы использовать pause () вместо цикла while, так как это действительно имеет больше смысла даже для демонстрационного кода. Как я уже сказал в посте, код изначально был взят из другого источника. Возможно, я неправильно его прочитал, но я подумал, что это сэкономит и восстановит любые существующие обработчики сигналов.

Mr. Muskrat 23.12.2008 20:07

Это хороший рабочий пример, но я думаю, что struct sigaction action, old_action; должно быть действием struct sigaction; То есть, похоже, вы переопределили имя своего глобального old_action в main ().

Dronz 12.10.2012 09:03

Обратите внимание, что sigaction не является частью ISO 9899 (стандарт C), тогда как signal входит в его состав. Для переносимости вместо этого может быть полезно использовать signal, особенно когда различия в реализации некритичны (например, обработчик сигнала, завершающий программу).

fuz 01.10.2015 15:31

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