55 votes

Peut-on geler temporairement un processus sous linux ?

Je me demandais s'il existe un moyen de geler un processus pendant un certain temps ?

Ce que je veux dire, c'est qu'il est possible pour une application (probablement exécutée en tant que root) de mettre en pause l'exécution d'un autre processus en cours d'exécution (n'importe quel processus, aussi bien en interface graphique qu'en ligne de commande) et de le reprendre plus tard ? En d'autres termes, je ne veux pas que certains processus soient programmés par le planificateur de linux pendant un certain temps.

87voto

Giuseppe R Points 1325

Véase aquí

Il y a dos des signaux qui peuvent suspendre l'exécution d'un processus. L'un est "gracieux", l'autre est "forcé".

Le "gracieux" est SIGTSTP et son but est de demander "gentiment" au processus, s'il en a envie, de suspendre son exécution jusqu'à ce qu'il reçoive un SIGCONT . Dans le cas de SIGTSTP le processus peut ignorer SIGTSTP et continuer à s'exécuter de toute façon, ce qui nécessite la coopération d'un programme conçu pour gérer SIGTSTP.

Celui qui est "énergique" est SIGSTOP et son but est de suspendre tous les threads de l'espace utilisateur associés à ce processus. Il est tout aussi impossible que le processus ignore SIGSTOP comme il l'est pour elle d'ignorer SIGKILL (ce dernier tue le processus avec force).

Pour envoyer un signal arbitraire, y compris n'importe lequel de ceux mentionnés ici, vous pouvez utiliser des programmes tels que kill , killall ou pkill ; ou utiliser l'appel système kill(2) . Consultez les pages de manuel de votre système d'exploitation pour obtenir des détails dépendants de la plate-forme/architecture/version et des errata concernant les éléments ci-dessus. Notez que le mot "kill" dans toutes ces commandes et dans le syscall est un mauvais terme. Ces commandes sont no conçu, exclusivement, pour mettre fin aux processus. Ils puede Mais les signaux peuvent également être utilisés pour d'autres fonctionnalités que la fin d'un processus. Par exemple, SIGSTOP ne fait que suspendre le processus, et ce n'est qu'un des nombreux signaux qui peuvent être envoyés de cette façon.

Pour ajouter une condition de reprise automatique du processus après une certaine période de temps, vous devrez utiliser une sorte de processus de surveillance qui reste en cours d'exécution et définit une minuterie afin de réveiller le processus de surveillance, qui appelle à son tour kill(2) à nouveau et envoie le SIGCONT au processus arrêté, afin de demander au noyau de reprendre l'exécution. Notez que Linux dispose de plusieurs mécanismes de chronométrage avec différents degrés d'exactitude et de précision ; en outre, si votre système est très occupé, votre processus de surveillance peut ne pas être réveillé avant que son chronomètre n'ait expiré, et le réveil peut donc être retardé.

Si vous dépendez de la précision très précise de la suspension et de la reprise du processus suspendu, vous devrez peut-être exécuter votre programme de surveillance avec des autorisations en temps réel (cf. cette page de manuel sur sched_setscheduler(2) pour des informations sur la façon de rendre votre processus en temps réel). Vous pouvez également utiliser les High-Resolution Timers, une fonctionnalité du noyau Linux (qui n'est disponible que si votre matériel les prend en charge), en combinaison avec la planification en temps réel, pour obtenir très une précision inférieure à la milliseconde sur le timing, puis se réveiller et envoyer le signal pour reprendre le processus surveillé très rapidement.

Vous n'avez pas indiqué quelles technologies vous êtes prêt à utiliser pour mettre en œuvre cette solution. Au minimum, vous aurez besoin d'un script bash, bien que vous ne puissiez pas obtenir un timing très fin de cette façon. Voici un script bash "script" (non testé, donc faites attention) qui est juste une preuve de concept de votre requête. Si vous avez besoin d'un timing précis, vous devrez écrire un programme, probablement en C/C++ ou dans un autre langage natif, et utiliser l'ordonnancement en temps réel et les hrtimers.

#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"

Notez que le script se terminera et le script de contrôle se terminera, mais en raison de screen contrôlant le processus de surveillance, il continuera à fonctionner en arrière-plan pendant 10 secondes (en fonction de l'argument passé à la commande sleep ) et ensuite se réveiller et continuer le processus de l'enfant. Mais cela se fera longtemps après que le script de contrôle se soit terminé. Si vous voulez attendre de manière synchrone que le temps s'écoule, il suffit d'omettre le deuxième appel à screen et coder en dur le sleep et le kill dans le script de contrôle.

Vous pouvez vérifier que le processus est bien suspendu en exécutant la commande suivante

screen -rS child

après avoir lancé ce script. Vous ne verrez rien sur la console. Puis, après l'expiration du timer (10 secondes), il inondera votre écran de données base64 (caractères aléatoires de 0-9 et A-F). Appuyez sur Ctrl+C pour quitter.

17voto

Oui, vous pouvez le faire en envoyant un STOP à un processus pour le suspendre et ensuite une CONT pour continuer.

l'usage :

kill -STOP <pid>

kill -CONT <pid>

12voto

Maurice Points 129

Si vous avez une définition assez large du terme "geler", vous pouvez consulter le site de la Commission européenne. renice commandement.

Renice vous permet de modifier la priorité d'ordonnancement des processus en cours.

La valeur normale de nice du processus est 0. Augmenter la valeur de nice rend le processus plus sympa, comme dans "pourquoi ne pas y aller en premier". Alors qu'en diminuant la valeur "nice", le processus devient moins agréable, comme dans "dégage de mon chemin, je suis pressé". La fourchette de valeurs est de -20 à 19.

Tout le monde peut rendre ses propres processus plus agréables. Seul root peut rendre un processus moins agréable ou changer l'aspect agréable des processus d'un autre utilisateur.

Si vous fixez la valeur de "nice" d'un processus à 19, il ne s'exécutera que si rien d'autre sur le système ne le veut.

Voici un exemple exécuté sur mon ordinateur local sous linux.

Utilice ps -l et regardez la colonne NI pour voir une belle valeur de processus.

\-> ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY     CMD
0 S 29190   402 31146  0  75   0 - 16547 wait   pts/0   bash
0 T 29190  1105   402  0  75   0 - 23980 finish pts/0   vim
0 R 29190   794   402  0  76   0 - 15874 -      pts/0   ps

Running renice +10 sur le processus vim le fait tourner à une priorité inférieure.

\-> renice +10 -p 1105
1105: old priority 0, new priority 10

-> ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY    CMD
0 S 29190   402 31146  0  76   0 - 16547 wait   pts/0  bash
0 T 29190  1105   402  0  95  10 - 23980 finish pts/0  vim
0 R 29190  1998   402  0  78   0 - 15874 -      pts/0  ps

En supposant que vous puissiez étendre le terme "geler" pour signifier "ne pas déranger les autres utilisateurs du système", vous pourriez scripter quelque chose du genre :

renice 20 -p <pid of interest>
sleep <certain amount of time>
renice 0 -p <pid of interest>

(n'oubliez pas de l'exécuter en tant que root).


Notez que j'ai pris quelques libertés avec le texte ci-dessus. ps -l sortie pour que les colonnes intéressantes apparaissent bien dans les petites boîtes bleues :)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X