signal handling (tsz. signal handlings)
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.
CTRL+C
, SIGINT
)SIGSEGV
)
<csignal>
)A <csignal>
könyvtár biztosítja az alapvető jelkezelési mechanizmusokat.
signal()
függvényA 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.
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) |
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ő.
sigaction()
– Haladó jelkezelés (POSIX)A signal()
egyszerű, de a sigaction()
pontosabb irányítást biztosít a jelek kezelése felett.
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()
.
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.
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.
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.
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! 🚀