Heim > Artikel > Betrieb und Instandhaltung > Wofür wird das Linux-Signal verwendet?
Linux-Signale werden verwendet, um den Prozess über das Auftreten eines bestimmten Ereignisses zu informieren oder den Prozess eine bestimmte Verarbeitungsfunktion ausführen zu lassen. Das Signal ist ein alter Kommunikationsmechanismus in der Unix-Familie; das Signal kann von der Tastatureingabe am Terminal stammen B. SIGINIT, ausgelöst durch Control-C, kann auch von Ausnahmen im Zusammenhang mit Hardware oder Software herrühren, z. B. SIGSEGV, ausgelöst durch eine Anwendung, die auf eine ungültige Adresse zugreift, SIGALARM, ausgelöst durch Timer-Ablauf usw.
Die Betriebsumgebung dieses Tutorials: Linux5.9.8-System, Dell G3-Computer.
Wofür wird das Linux-Signal verwendet?
Signalverarbeitungsmechanismus in Linux
Signal ist ein alter Kommunikationsmechanismus in der Unix-Familie. Er wird hauptsächlich verwendet, um den Prozess über das Auftreten eines bestimmten Ereignisses zu informieren oder den Prozess eine bestimmte Verarbeitungsfunktion ausführen zu lassen. Es gilt als uralt, da es bereits in der ersten Generation von Unix-Systemen existierte.
Das Signal kann von der Tastaturzeicheneingabe des Terminals stammen, z. B. SIGINIT, ausgelöst durch Control-C; es kann auch von Ausnahmen im Zusammenhang mit Hardware oder Software stammen, z. B. SIGSEGV, ausgelöst durch die Anwendung Zugriff auf eine ungültige Adresse (Segmentierungsfehler), SIGALARM ausgelöst durch Timer-Ablauf usw. Diese Signale werden vom Kernel an den Prozess gesendet.
Die vom Prozess empfangenen Signale können auch von anderen Prozessen stammen. Aber nicht alle Prozesse können Signale an andere Prozesse senden. Nur Superuser mit Root-Berechtigungen können dies tun. Bei normalen Benutzerprozessen können sie nur Signale an Prozesse senden, die demselben Benutzer gehören.
Kann der Prozess Signale an den Kernel senden? Ja, das ist möglich, aber der Kernel-Thread antwortet nicht und es ist nutzlos, es sei denn ... Sie ändern den Kernel-Code.
Normalerweise werden Signale als asynchroner Mechanismus betrachtet, aber im Linux-Code werden die folgenden durch Ausnahmen verursachten Signale auch als „synchron“ bezeichnet:
#define SYNCHRONOUS_MASK \ (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))
Hier nennen wir den Prozess, der das Signal empfängt, „Zielprozess“. Die traditionelle Signalsendefunktion ist kill(). Dieser Name sieht beängstigend aus und es fühlt sich an, als würde der Zielprozess gleich „getötet“ werden. Obwohl alle Signale mit kill() gesendet werden, wird tatsächlich nur ein kleiner Teil der Prozesse tatsächlich „getötet“. Natürlich gibt es jetzt sigqueue() mit leistungsfähigeren Funktionen und einem freundlicheren Namen.
Werfen wir einen Blick auf die Funktionsprototypen der beiden:
int kill(pid_t pid, int sig);int sigqueue(pid_t pid, int sig, const union sigval value);
pid repräsentiert die PID des Zielprozesses. Die PIDs von Prozessen in Linux sind alle positive Zahlen. Wenn der Wert des Parameters pid 0 oder eine negative Zahl ist, ist das illegal? Nein, tatsächlich haben 0 und negative Zahlen hier andere Verwendungszwecke. Unter Linux gibt es ein Konzept der Prozessgruppe, das eine Sammlung von Prozessen eines Typs darstellt. Wenn in kill() der Parameter pid „0“ ist, bedeutet dies, dass das Signal an alle Prozesse in der Prozessgruppe gesendet wird, in der sich der aktuelle Prozess befindet. Wenn er kleiner als „-1“ ist, wird das Signal an gesendet Die Prozessgruppe hat die Nummer -pid.
__kill_pgrp_info(sig, info, pid ? find_vpid(-pid) : task_pgrp(current));
pid ist „-1“, was bedeutet, dass es an alle Prozesse außer dem Init-Prozess und sich selbst oder an alle Prozesse mit einer PID größer als 1 außer sich selbst gesendet wird.
for_each_process(p) {
if (task_pid_vnr(p) > 1 && !same_thread_group(p, current))
...
Wenn pid hier die eigene PID des Prozesses ist, dann sendet der Prozess ein Signal an sich selbst. Zu diesem Zweck stellt Linux auch eine einfachere Schnittstelle zur Verfügung: die Funktion raise().
kill(getpid(), sig) --> raise(sig)
Es ist zu beachten, dass Sie in sigqueue() kein Signal an die gesamte Prozessgruppe senden können, indem Sie den Wert des Parameters pid auf eine negative Zahl setzen.
sig stellt die Nummer des zu sendenden Signals dar. Die Signalnummer beginnt in Linux bei 1. Was passiert, wenn der Wert des Parameters sig 0 ist? Die 0 hat hier auch einen magischen Effekt. Wenn das Signal „0“ ist, wird kein Signal an den Zielprozess (oder die Zielprozessgruppe) gesendet, sondern es wird verwendet, um zu erkennen, ob der Zielprozess (oder die Zielprozessgruppe) existiert.
Der dritte von Sigqueue hinzugefügte Parameter lautet wie folgt:
union sigval {
int sival_int;
void __user *sival_ptr;};
传统的信号是没有传递消息的功能的,sigval算是稍微扩展了一下信号的通信能力。比如,通信双方可以事先约定某些事件为特定的int值,这个"sival_int"就可以用来保存具体的int值,目标进程可以据此来区分不同的事件,做出不同的响应。当然,这种方法传递的消息内容受限,且不易扩展,因而不适合用作常规的通信手段。
就算是进程之间发送信号,那也是要经过内核的,可以理解成是被内核“截获”了吧。
由于内核态和用户态的切换操作在不同的硬件体系架构上是不同的,而且有一些信号,比如SIGCHLD和SIGSTOP,其实现也是和架构相关的,所以Linux中signal机制的很多代码都是放在架构相关的目录下的,比如"/arch/arm/kernel/signal.c"。
一个信号的相关信息在内核中用siginfo_t结构体表示:
siginfo_t{
int si_signo;
int si_sicode;
union __sifields _sifields;
...}
内核在截获到一个进程发送的信号后,会首先做一系列的检查,比如该信号的值是否合法啦,进程有没有发送这个信号的权限啦。如果检查通过,就调用copy_from_user()将该信号的相关信息复制到siginfo_t结构体中。
相关推荐:《Linux视频教程》
Das obige ist der detaillierte Inhalt vonWofür wird das Linux-Signal verwendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!