Question Comment vérifier si un processus est non bloquant sous Linux sans utiliser un traceur de pile?


Un serveur multi-processeurs exécute plusieurs processus. Un processus a un thread qui devrait toujours être dans un état de rotation, en utilisant 100% du CPU qui lui a été attribué. Ma méthode actuelle (en plus de demander au développeur ...) utilise strace sur le processus qui attend que les informations parviennent à son descripteur de fichier ouvert et le vérifie en permanence à l'aide de recvfrom(2) où erno est réglé sur EAGAIN et la méthode renvoie -1 quand aucun paquet ne doit être lu depuis le socket réseau.

Je ne suis pas à l'aise avec le traçage des piles dans les configurations de production, et c'est un moyen difficile de déterminer au mieux ces informations. Je cherchais proc(5) et a pensé que la valeur du champ flags dans /proc/[pid]/fdinfo peut être utile pour vérifier si ce processus utilisait un socket qui a appelé open(2) avec le O_NONBLOCK mode.

J'ai du mal à faire de l'ingénierie inverse cette valeur pour le moment. Je sais qu'il représente le OU au niveau du bit du statut et du mode du fichier. Je pense donc pouvoir vérifier dans les en-têtes de source la valeur des constantes open(2) utilise sur ce noyau particulier et ensuite au niveau du bit OU jusqu'à ce que je trouve une valeur qui correspond à ce qui est dans fdinfo. Cela semble assez maladroit, si quelqu'un peut valider la méthode ci-dessus (je ne le peux pas encore) ou fournir une solution plus élégante, je serais très obligé.

Je sais aussi fnctl(2) peut définir un descripteur de fichier sur un état non bloquant, mais je traite cet équivalent pour l'ouvrir pour le moment


4
2018-03-31 21:35


origine


La commande top ne montre-t-elle pas le processus en utilisant 100% d'un noyau de votre CPU? - Sirex
Pourquoi est-il important de pouvoir prouver que le programme se comporte mal autrement strace? Vous savez déjà que c'est cassé, allez le renvoyer aux développeurs. - Michael Hampton♦
L'utilisation de top est valide, mais pas définitive, les processus peuvent utiliser 100% de la CPU sans pour autant être en cours d'exécution en mode non bloquant. Un humain pourrait facilement dire regarder en haut, mais une vérification de script en interrogeant tout en haut signalait parfois des faux positifs. @MichaelHampton - la fonctionnalité souhaitée n'est pas un blocage, mais un bogue dans ce cas. - inetplumber
le s préfixe dans strace n'est pas "pile". - Ben Voigt


Réponses:


Oui, il s'agit d'un moyen valide de vérifier que le socket est non bloquant.

La valeur pour un socket non bloquant est 04000, les sockets non bloquants en /proc/<pid>/fdinfo sont représentés en octal.

Vous pouvez valider ce comportement avec python.

Python 2.7.5 (default, Feb 19 2014, 13:47:28) 
[GCC 4.8.2 20131212 (Red Hat 4.8.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import *
>>> import os
>>> from os import O_NONBLOCK
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.setblocking(0)
>>> print open("/proc/self/fdinfo/{0}".format(s.fileno())).read(4096)
pos:    0
flags:  04002

>>> if 04002 & O_NONBLOCK:
...   print "yes"
... else:
...   print "no"
... 
yes

Alors, maintenant vous savez comment, je dois souligner que votre développeur est mal le faire. Si vous voulez utiliser des sockets non-bloquants, c’est très bien - mais ils doivent configurer un epoll(2) sur le socket et bloquer le sondage à la place.

Le programme gagne rien de read(2) sur une prise non bloquante qui produit EAGAIN - en fait, le résultat est pire car presque tous les appels système sont un point de préemption où le noyau peut quand même vous changer de contexte.

Ce développeur gaspille de l’énergie, des cycles de processeur qui pourraient être utilisés pour les threads inactifs et n’obtient pas réellement d’avantages, contrairement à ce qu’il est en train de faire.

Si le développeur souhaite utiliser la «ligne de cache», épinglez ses tâches sur un processeur particulier et terminez-le.


11
2018-03-31 22:28