signal handling
Főnév
signal handling (tsz. signal handlings)
Jelkezelés (Signal Handling) C++ nyelven
Bevezetés
A signal handling egy mechanizmus, amely lehetővé teszi, hogy egy program reagáljon bizonyos rendszereseményekre vagy megszakításokra. A jelek (signals) aszinkron események, amelyeket az operációs rendszer küld egy folyamatnak.
A C++ nem rendelkezik beépített jelkezelési támogatással, de a C standard library (<csignal>, POSIX API) segítségével a programok kezelhetik ezeket az eseményeket.
Mikor használjuk a jelkezelést?
- Felhasználói megszakítások (
CTRL+C,SIGINT) - Folyamatok közötti kommunikáció (IPC)
- Memóriakezelési hibák (
SIGSEGV) - Időzítések, időtúllépések
- Bizonyos események figyelése és kezelése
1. Alapvető signal handling (<csignal>)
A <csignal> könyvtár biztosítja az alapvető jelkezelési mechanizmusokat.
1.1. signal() függvény
A signal() függvény segítségével regisztrálhatunk egy függvényt egy adott jel kezelésére.
#include <iostream>
#include <csignal>
using namespace std;
// Signal kezelő függvény
void signalHandler(int signalNum) {
cout << "Jel (" << signalNum << ") fogadva. A program befejeződik." << endl;
exit(signalNum); // Program kilépése a jel után
}
int main() {
signal(SIGINT, signalHandler); // SIGINT (CTRL+C) kezelése
cout << "Nyomd meg a CTRL+C billentyűkombinációt a kilépéshez..." << endl;
while (true) { } // Végtelen ciklus (várja a megszakítást)
return 0;
}
📌 Magyarázat:
- signal(SIGINT, signalHandler) – Ha a felhasználó CTRL+C-t nyom, a signalHandler() függvény fut le. - exit(signalNum) – A program kilép, amikor a jel érkezik.
2. Gyakori jelek (signal numbers)
| Jel neve | Érték | Leírás |
|---|---|---|
SIGINT |
2 | Interruption – pl. CTRL+C |
SIGTERM |
15 | Kill – Program bezárása |
SIGKILL |
9 | Hard Kill (nem kezelhető) |
SIGSEGV |
11 | Segmentation Fault (érvénytelen memóriahozzáférés) |
SIGFPE |
8 | Floating Point Exception (osztás nullával) |
SIGABRT |
6 | Abort hívás (abort()) |
SIGHUP |
1 | Kapcsolat megszakadása (terminál bezárás) |
3. Több jel kezelése
A signal() segítségével egyszerre több jelet is kezelhetünk.
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signalNum) {
if (signalNum == SIGINT) {
cout << "SIGINT (CTRL+C) fogadva!" << endl;
} else if (signalNum == SIGTERM) {
cout << "SIGTERM fogadva! Kilépés..." << endl;
exit(0);
}
}
int main() {
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
cout << "Nyomj CTRL+C-t vagy küldj egy SIGTERM jelet a kilépéshez." << endl;
while (true) { } // Végtelen ciklus
return 0;
}
📌 Magyarázat:
- SIGINT (CTRL+C) és SIGTERM különböző módon kezelhető.
4. sigaction() – Haladó jelkezelés (POSIX)
A signal() egyszerű, de a sigaction() pontosabb irányítást biztosít a jelek kezelése felett.
4.1. sigaction() használata
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signalNum) {
cout << "Jel fogadva: " << signalNum << endl;
}
int main() {
struct sigaction sa;
sa.sa_handler = signalHandler; // Jelkezelő függvény
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL); // SIGINT-re alkalmazzuk
cout << "Nyomd meg a CTRL+C-t!" << endl;
while (true) { }
return 0;
}
📌 Előnyök sigaction() esetén: - Pontosabb jelkezelés, mert több paramétert használ. - Sokkal biztonságosabb, mint a signal().
5. Jel küldése egy másik folyamatnak (kill())
Linux és macOS rendszereken a kill() függvény segítségével jelet küldhetünk egy másik folyamatnak.
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
int main() {
pid_t pid;
cout << "Add meg a folyamat PID-jét: ";
cin >> pid;
if (kill(pid, SIGTERM) == 0) {
cout << "SIGTERM jel elküldve a " << pid << " PID-nek." << endl;
} else {
cout << "Hiba a jel küldése közben!" << endl;
}
return 0;
}
📌 Megjegyzés: - kill(pid, SIGTERM) – Küld egy SIGTERM jelet a pid folyamatnak. - Hasznos folyamatok közötti kommunikációhoz vagy folyamatok leállításához.
6. Osztás nullával (SIGFPE kezelése)
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signalNum) {
cout << "Hiba: osztás nullával! (" << signalNum << ")" << endl;
exit(signalNum);
}
int main() {
signal(SIGFPE, signalHandler);
int x = 10, y = 0;
int z = x / y; // Itt osztás nullával történik!
cout << "Ez a sor nem fog lefutni." << endl;
return 0;
}
📌 Ha az osztás nullával történik, a SIGFPE jel aktiválódik, és a program kezelni tudja azt.
7. Windows jelkezelés
Windows rendszeren a signal() szintén működik, de néhány jel (pl. SIGKILL) nem támogatott.
#include <iostream>
#include <csignal>
#include <windows.h>
using namespace std;
void signalHandler(int signalNum) {
cout << "Jel fogadva: " << signalNum << endl;
exit(signalNum);
}
int main() {
signal(SIGINT, signalHandler); // CTRL+C kezelés
cout << "Nyomd meg a CTRL+C-t!" << endl;
while (true) { Sleep(100); } // Végtelen ciklus Windows alatt
return 0;
}
📌 Megjegyzés: - Windows nem támogatja az összes POSIX jelet (SIGKILL, SIGSTOP). - A Sleep(100) megakadályozza, hogy a CPU 100%-on fusson.
Összegzés
| Függvény | Leírás |
|---|---|
signal(SIGINT, handler) |
Egyszerű jelkezelés (CTRL+C) |
sigaction(SIGINT, &sa, NULL) |
Fejlettebb POSIX jelkezelés |
kill(pid, SIGTERM) |
Jel küldése egy folyamatnak |
raise(SIGTERM) |
Saját program jelzése saját magának |
exit(code) |
Program kilépése egy jel alapján |
Mikor használjuk?
✅ Ha folyamatokat szeretnénk irányítani
✅ Ha hibakezelést szeretnénk megvalósítani
✅ Ha folyamatok közötti kommunikációt végzünk
A jelkezelés segít stabilabb és megbízhatóbb programok létrehozásában! 🚀
- signal handling - Szótár.net (en-hu)
- signal handling - Sztaki (en-hu)
- signal handling - Merriam–Webster
- signal handling - Cambridge
- signal handling - WordNet
- signal handling - Яндекс (en-ru)
- signal handling - Google (en-hu)
- signal handling - Wikidata
- signal handling - Wikipédia (angol)