A quoi sert le signal Linux ?

藏色散人
Libérer: 2023-04-10 11:17:41
original
1521 Les gens l'ont consulté

Le signal Linux est utilisé pour notifier le processus de l'occurrence d'un événement spécifique ou pour permettre au processus d'exécuter une fonction de traitement spécifique ; le signal est un ancien mécanisme de communication de la famille Unix. Le signal peut provenir de la saisie d'un caractère au clavier sur le terminal ; , comme SIGINIT déclenché par control-C peut également provenir d'exceptions liées au matériel ou au logiciel, comme SIGSEGV déclenché par une application accédant à une adresse invalide, SIGALARM déclenché par l'expiration d'un timer, etc.

A quoi sert le signal Linux ?

L'environnement d'exploitation de ce tutoriel : système linux5.9.8, ordinateur Dell G3.

À quoi sert le signal Linux ?

Mécanisme de traitement du signal sous Linux

Le signal est un ancien mécanisme de communication de la famille Unix. Il est principalement utilisé pour notifier le processus de l'occurrence d'un événement spécifique ou pour permettre au processus d'exécuter une fonction de traitement spécifique. On dit qu'il est ancien car il existait dans la première génération des systèmes Unix.

Envoi de signaux

Le signal peut provenir de la saisie de caractères au clavier du terminal, comme SIGINIT déclenché par control-C il peut également provenir d'exceptions liées au matériel ou au logiciel, comme SIGSEGV déclenché par l'application ; accès à une adresse invalide (défaut de segmentation), SIGALARM déclenchée par expiration du timer, etc. Ces signaux sont envoyés au processus par le noyau.

Les signaux reçus par le processus peuvent également provenir d'autres processus. Mais tous les processus ne peuvent pas envoyer de signaux à d'autres processus. Seuls les super-utilisateurs disposant des autorisations root peuvent le faire. Pour les processus utilisateur ordinaires, ils ne peuvent envoyer des signaux qu'aux processus appartenant au même utilisateur.

Le processus peut-il envoyer des signaux au noyau ? Oui, c'est possible, mais le thread du noyau ne répondra pas, et cela ne servira à rien à moins que... vous ne modifiiez le code du noyau.

Habituellement, les signaux sont considérés comme un mécanisme asynchrone, mais dans le code Linux, les signaux suivants provoqués par des exceptions sont également appelés « synchrones » :

#define SYNCHRONOUS_MASK \	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))
Copier après la connexion

Ici, nous appelons le processus qui reçoit le signal « processus cible ». La fonction traditionnelle d'envoi de signal est kill(). Ce nom semble effrayant et donne l'impression que le processus cible est sur le point d'être "tué". En fait, bien que tous les signaux soient envoyés à l'aide de kill(), seule une petite partie des processus est réellement « tuée ». Bien sûr, il existe désormais sigqueue() avec des fonctions plus puissantes et un nom plus convivial.

Jetons un coup d'œil aux prototypes de fonction des deux :

int kill(pid_t pid, int sig);int sigqueue(pid_t pid, int sig, const union sigval value);
Copier après la connexion

pid représente le PID du processus cible. Les PID des processus sous Linux sont tous des nombres positifs. Si la valeur du paramètre pid est 0 ou un nombre négatif, est-ce illégal ? Non, en fait, les nombres 0 et négatifs ont ici d’autres utilisations. Il existe un concept de groupe de processus sous Linux, qui représente un ensemble de processus d'un type. Dans kill(), si le paramètre pid est "0", cela signifie que le signal est envoyé à tous les processus du groupe de processus où se trouve le processus actuel. S'il est inférieur à "-1", le signal est envoyé à. le groupe de processus numéroté -pid.

__kill_pgrp_info(sig, info, pid ? find_vpid(-pid) : task_pgrp(current));
Copier après la connexion

pid est "-1", ce qui signifie qu'il est envoyé à tous les processus sauf le processus Init et lui-même, ou à tous les processus avec un pid supérieur à 1 sauf lui-même.

for_each_process(p) {
	if (task_pid_vnr(p) > 1 && !same_thread_group(p, current)) 
            ...
Copier après la connexion

Si pid ici est le propre PID du processus, alors le processus s'envoie un signal. Pour cela, Linux propose également une interface plus simple : la fonction raise().

kill(getpid(), sig) --> raise(sig)
Copier après la connexion

Il convient de noter que dans sigqueue(), vous ne pouvez pas envoyer de signal à l'ensemble du groupe de processus en définissant la valeur du paramètre pid sur un nombre négatif.

sig représente le numéro du signal à envoyer Le numéro du signal sous Linux commence à 1. Que se passera-t-il si la valeur du paramètre sig est 0 ? Le 0 ici a également un effet magique Lorsque sig est "0", il n'envoie pas réellement de signal au processus cible (ou au groupe de processus), mais est utilisé pour détecter si le processus cible (ou le groupe de processus) existe.

Quant au troisième paramètre ajouté par sigqueue, sa définition est la suivante :

union sigval {
	int sival_int;
	void __user *sival_ptr;};
Copier après la connexion

传统的信号是没有传递消息的功能的,sigval算是稍微扩展了一下信号的通信能力。比如,通信双方可以事先约定某些事件为特定的int值,这个"sival_int"就可以用来保存具体的int值,目标进程可以据此来区分不同的事件,做出不同的响应。当然,这种方法传递的消息内容受限,且不易扩展,因而不适合用作常规的通信手段。

信号的内核处理

就算是进程之间发送信号,那也是要经过内核的,可以理解成是被内核“截获”了吧。

A quoi sert le signal Linux ?

由于内核态和用户态的切换操作在不同的硬件体系架构上是不同的,而且有一些信号,比如SIGCHLD和SIGSTOP,其实现也是和架构相关的,所以Linux中signal机制的很多代码都是放在架构相关的目录下的,比如"/arch/arm/kernel/signal.c"。

一个信号的相关信息在内核中用siginfo_t结构体表示:

siginfo_t{
    int si_signo;
    int si_sicode;
    union __sifields _sifields;
    ...}
Copier après la connexion
  • si_signo是信号的编号,从1到64的值都是合法的。
  • si_sicode记录了信号的来源,比如SI_USER表示信号是由进程调用kill()发出的,SI_QUEUE是由进程调用sigqueue()发出的,SI_KERNEL则说明该信号由内核产生的。
  • _sifields对不同的信号会有不同的含义,通常包括信号发送进程的si_pid,发送进程所属user的si_uid等。对于由sigqueue()发送的信号,还包括"sigval "参数所携带的附加信息。

内核在截获到一个进程发送的信号后,会首先做一系列的检查,比如该信号的值是否合法啦,进程有没有发送这个信号的权限啦。如果检查通过,就调用copy_from_user()将该信号的相关信息复制到siginfo_t结构体中。

相关推荐:《Linux视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal