/ / Ctrl-C problem w obsłudze C-Signal - c

Problem Ctrl-C w obsłudze C-Signal - c

Mam pytanie dotyczące obsługi sygnałów.

Powiedzmy, że mam dwa programy uruchomione w tym samym czasie. Nazywam je programami 1 i program2.

Używam ich w osobnych terminalach, ponieważjeden program czeka na rozpoczęcie drugiego. Zostały zaprojektowane tak, aby działały dopóki nie dotknę ctrl-c w obu oknach. Uważam, że ta metoda jest trochę kłopotliwa. Więc chcę coś dodać do jednego z programów.

Oznacza to, że mogę użyć ctrl-c, aby zatrzymać program1 iProgram2 zatrzyma się, gdy wie, że program1 nie jest już aktywny. Sprawdziłem online, czy istnieje przykład tego lub jakiejś części w języku C, którego nie znam i natknąłem się na obsługę sygnałów.

Wiem, że obsługa sygnałów polega na tym, że program wykonuje różne wykonania w zależności od podanego sygnału lub struktury sygnału. Czy jest to właściwa metoda użycia lub czy istnieje inny sposób?

Widziałem online, że za pomocą obsługi sygnału może zepsuć polecenie Ctrl-C w terminalu, jeśli sygnał jest ctrl-C?

Wyjaśnienia dotyczące obsługi sygnałów byłyby również mile widziane z przykładowym kodem.

Na podstawie podanych odpowiedzi, zapisałem przykładowy kod zgodnie z podanym:

#include <signal.h>
......
......
sigset_t SIGUSR1;
sigset_t SIGUSR2;
int signal;

void trap(int signal);
......
......
void trap(int signal)
{
int signal;
signal == SIGUSR1
}

Przepraszam, jeśli wyglądam głupio, że to piszę, ale nadal chcę wiedzieć, jak to działa.

Odpowiedzi:

0 dla odpowiedzi № 1

"czy jest inny sposób?" - tu jest odpowiedź ukośna UNIX.

Ten temat jest bardzo szeroki - nazywa się IPC - Interprocess Communication. Współpracujące procesy mogą "rozmawiać" ze sobą za pomocą wielu metod, sygnały to tylko jeden, oto kilka sposobów:

signals
shared memory objects
sockets
message queues
files

Sygnały mają nazwę SIG [coś] i są wewnętrznie reprezentowane w kernelu jako liczba. kill -l wyświetli listę dostępnych sygnałów i ichnazwiska dla ciebie. SIGUSR1 i SIGUSR2 są przeznaczone dla aplikacji użytkowników do komunikowania się ze sobą. Rozważ użycie ich. Nie przejmuj się liczbą, którą reprezentuje SIGUSR1, po prostu użyj nazwy w swoim kodzie.

Aby użyć sygnałów: Na odbiorze przechwytujesz sygnał i ustawiasz zmienną globalną. Na końcu nadawania zadzwoń kill() funkcjonować.

SIGINT (CTRL / C) jest używany przez terminal do zatrzymanialub przerywać uruchomione procesy. Dlatego warto rozważyć użycie SIGUSR1 i SIGUSR2. Zwracając uwagę na SIGINT, zauważysz, że możesz stworzyć sytuację, w której musisz użyć CTRL / C. Ale jest uwięziony przez twój kod, więc nie ma żadnego efektu. SIGUSRn nie ma tego problemu. Nie musisz się więc martwić konkurowaniem o użycie (wiele znaczeń) pojedynczego sygnału.

Szczegóły systemu Linux: Spróbuj tego linku z tldp.org: http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf

Edytować:

prog1, ten, który czeka:

volatile int go=0;
void s_handler(int sig)
{
go=1;
}


int main()
{
signal(SIGUSR1, s_handler);
while(go==0)
usleep(500);
//  run the rest of the code here when I wake up
return 0;
}

prog2, ten, który budzi się prog1 - potrzebujesz pid z prog1. przekazać pid jako argument wiersza poleceń prog2 [pid goes here]

int main(int argc, char **argv)
{
if(argc>1)
{
pid_t pid=(pid_t)atoi(argv[1]);
if(kill(pid, 0)==0 &&  kill(pid, SIGUSR1)!=0)// check pid, then signal
{
perror("Can"t send signal to other process");
exit(1);
}
}
// run the rest of the code here
return 0;
}

Nie ma jednego najbardziej właściwego sposobu obsługi IPC. Wybierz jedno. Powyższe wykorzystuje sygnały.

Nie ma błędu sprawdzania samej logiki bazowej. Innym sposobem, aby to zrobić, jest napisanie pliku progu prog1 do pliku, prog2 następnie odczytuje plik, odczytuje i używa tego pid, a następnie usuwa plik. Zamiast argumentu wiersza poleceń.

Ty decydujesz.


1 dla odpowiedzi nr 2

Możesz obsługiwać sygnał za pomocą nagłówka signal.h na CTRL+C jest obsługiwane za pomocą SIGINT

może działać jak:

   void func(int sig)
{
switch(sig)
{
case SINGINT:
//Do whatever you want
break;
default :
break;
}
}

int main()
{
//Handle SIGINT
signal(SIGINT,func);

return 0;
}