CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C]prog système,relancement auto service

sd460
sd460
Niveau 10
19 novembre 2010 à 11:54:57

dnob700 :d) ah ok.
Effectivement : errno vaut 10 ce qui correspond effectivement à ECHILD.
Donc si je comprends bien, le service lancé n'est pas un fils de mon programme ? Du coup le waitpid ne peut pas fonctionner avec mon service... Donc finalement, execve ne correspond pas pour ce que je veux faire, c'est ca :question:

Pour le fscanf(), je récupère le pid du programme que je lance (au démarrage, le programme écrit son PID dans ce fichier, donc j'attends qu'il le l'écrive et je le lis).

"Celà dit, dans le processus père, fork renvoie le pid du processus fils. Est-ce qu'il correspond avec le pid que tu récupère par ton fscanf (que, honnêtement, je ne comprend pas)."
:d) non, ce n'est pas le meme.

dnob700
dnob700
Niveau 10
20 novembre 2010 à 13:06:43

godrik : je crois que lorsque ton père meurt, tu es adopté par init. Il y a quelques complication quand tu utilise clone à la place de fork, pour pouvoir gérer des thread au lieu de processus, mais je ne crois pas que ça puisse servir ici.

"non, ce n'est pas le meme." : voilà, je pense (comme dis au dessus), que tu ne peut pas utiliser wait pour attendre un processus dont ut n'es pas le père.

sd460
sd460
Niveau 10
20 novembre 2010 à 13:23:37

mmmmh... Du coup, la seule solution pour répondre à mon problème reste un cron qui lance un script bash avec un petit ps couplé au grep qui correspond :question: C'est ce que je voulais faire au début, après je me suis dit qu'il y avait peut-être plus élégant.

Merci pour votre support en tout cas :-)

dnob700
dnob700
Niveau 10
21 novembre 2010 à 13:33:21

Il y a certainement plein d'autre moyen que ça. Tu pourrais quand même écrire ton programme qui attend et qui a interval régulier appel ps ou équivalent (plutôt que de le lancer par cron).

Sinon, il y a bien un moyen pour adopter un processus (et peut-être d'autre que je ne connais pas). C'est l'appel système ptrace. Mais c'est probablement l'appel système le plus difficile à utiliser (en tout cas parmi ceux que je connais).

Une fois que tu connais le pid du processus que tu veux surveiller, tu fait :
ptrace(PTRACE_ATTACH, pid, 0, 0);

Ça te fait adopter le processus, mais aussi tu es prévenu à chaque fois qu'il reçoit un signal. Comme tu es son père adoptif, tu dois en prendre soin et le surveiller...(il y a une petite race-condition ici si jamais le processus meurt entre ta découverte de son pid et l'appel à ptrace)

Pour ça, tu dois avoir une boucle dans laquelle tu fait quelque chose du genre:

int status;
waitpid(pid, &status, 0); // rend la main à chaque "signalisation" du processus
if (WIFEXITED(status))
{
//ton processus c'est terminé, il faut le relancer
}
else
{
//Un signal est reçu par le processus il faut le lui relayer (oui, le père adoptif est précautionneux, il surveille tout ce que reçoit son fils).
int signal = 0;
if (WIFSTOPPED(status))
signal = WSTOPSIG(status);
else if (WIFCONTINUED(status))
signal = SIGCONT;
if (signal==SIGSTOP)
signal = 0;

ptrace(PTRACE_CONT, pid, 0, signal);
}

Bon, j'ai écrit ça rapidement à cout de manpage (et évidemment ce n'est pas testé). ptrace c'est essentiellement de la magie noire, la documentation est très parcellaire et il faut se plonger dans les source de la libc et du noyau pour comprendre comment ça fonctionne. Donc le code là est probablement approximatif et ne dois pas gérer correctement tout les cas.

L'avantage de cette méthode est que tu ne fait pas tourner un programme pour rien ou réveiller un programme à interval régulier pour surveiller le fils. Tu es prévenu lorsqu'il se passe quelquechose d'intéressant. Par contre, si ton fils adoptif reçoit beaucoup de signaux (mais vraiment beaucoup) alors tu aura une perte de performance à cause des changement de contexte qu'il faut faire pour les traiter.

À noter aussi que, avec cet appel ptrace, tu pourrais "tracer" directement le fils de ton processus (celui que tu fork/exec) puis surveiller quand celui-ci crée à son tour de nouveaux processus et obtenir directement leur pid (et les tracer). Mais en C c'est une vrai plaie à mettre en place pour les raisons évoquées ci-dessus.

sd460
sd460
Niveau 10
25 novembre 2010 à 19:35:40

ok, j'ai capté le principe. Merci pour ces explications.
Effectivement l'utilisation du ptrace semble délicate pour un non-initié... Je vais me contenter du cron je crois.

J'ai juste essayé pour voir ce que ca donnait , je recois ce message d'erreur à la compilation :
"error: lvalue required as left operand of assignment" quand on affecte les signaux. J'ai essayé de parser avec un (int) devant sans succès.

godrik
godrik
Niveau 30
25 novembre 2010 à 20:59:54

donne un bout de code

dnob700
dnob700
Niveau 10
27 novembre 2010 à 14:36:39

oui, ça c'est une erreur de C et non pas d'utilisation de ptrace. Il y a un moment ou tu veux enregistrer quelque chose et ce qu'il y a à gauche du digne égale n'est pas une variable.

sd460
sd460
Niveau 10
29 novembre 2010 à 18:04:49

zut, j'ai oublié de copier la ligne :honte:
de mémoire c'était là :
signal = WSTOPSIG(status);
signal = SIGCONT;

Je reconfirme quand j'aurai le code sous les yeux :)

dnob700
dnob700
Niveau 10
30 novembre 2010 à 21:43:50

mets tout le bout de code concerné sur un wall. Tu as du faire une erreur dans la définition de signal par exemple.

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de Jeux
  • Programmation
  • Création de sites web
  • Linux
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment