Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

question de base sur l'informatique

1 réponse
Avatar
siger
Bonjour,

il me semble que cette question a sa place sur fr.comp.developpement,
mais je n'en suis pas sûr, alors je double sur fr.comp.divers et vous
demande de me rediriger au bon endroit :-)

Je m'interroge sur un fonctionnement de base de l'informatique.

Quand un logiciel attend une action : un clic de souris, une frappe au
clavier ou tout autre chose, comment fait-il pour distinguer l'action
de l'inaction ?

Mon hypothèse est qu'il y a un truc qui tourne sans arrêt pour aller
vérifier l'état des... heu... "interupteurs", mais on me dit que c'est
pas ça (sans me dire ce que c'est)

Vous savez ?

--
siger

1 réponse

Avatar
Marc SCHAEFER
In fr.comp.developpement siger wrote:
Quand un logiciel attend une action : un clic de souris, une frappe au
clavier ou tout autre chose, comment fait-il pour distinguer l'action
de l'inaction ?

En fait, la plupart des logiciels manipulant des interfaces graphiques
utilisent un modèle de programmation appelé `événementiel'.
Dans son implémentation la plus simple, on peut imaginer que les
actions attendues (les événements) sont simplement liés à des
fonctions de votre logiciel. Lorsque l'événement X survient, la
fonction traiter_X() est appelée. On appelait cela il y a longtemps
des `callbacks'. Ces callbacks doivent être associés aux événements
en appelant une fonction de l'OS ou du GUI correspondant.
L'inaction est donc quand après un certain délai (un délai est
aussi un événement dans ce modèle, c'est plus simple), rien ne s'est passé.
En supposant un système géré de manière séquentielle(*), le pseudo-code
ressemblerait(**) à:
int il_a_clique = 0;
associer(UN_CLICK, &traiter_CLIC);
associer(UN_DELAI_DE_5_SECONDES, &traiter_DELAI);
void traiter_CLIC() {
il_a_clique = 1;
// alternative: annuler le délai et directement appeler traiter_DELAI()
}
void traiter_DELAI() {
if (il_a_clique) {
puts("click reçu");
}
else {
puts("t'as pas clique");
}
}
Une autre technique est de transformer ces appels directs de
fonctions par des messages (des octets dans un pipeline, dans un
socket, dans une connexion TCP, etc). L'avantage de cette sérialisation
est la possibilité de prioriser les événements à la réception, la
détection du non traitement des événements après un timeout ("l'application
X ne répond pas"), et la possibilité de faire des interfaces graphiques
déportées (cf ssh -X) de manière triviale ou presque.
Dans ce cas, le logiciel est conçu comme un gros:
while (1) {
m = lire_message();
traiter_message(m);
}
La fonction lire_message() est bloquante (le processus est endormi
par l'OS). Ca peut d'ailleurs même marcher avec des OS non réellement
multitâches: on autorise l'OS à changer de tâche alors uniquement au
sein de lire_message() par un `yield()' manuel, p.ex. Ca a dû être ainsi
que le multitâche dit `coopératif' de certains vieux OS fonctionnait.
En conséquence, si traiter_message() prend trop de temps, sur ces
vieux OS, l'expérience utilisateur sera très saccadée. Je crois savoir
que Javascript dans un navigateur Web est en fait un langage de ce type,
les experts commenteront.
(*) si au contraire, les événements peuvent être traités en parallèle,
le code ci-dessous n'est pas bon car il ne gère pas la concurrence
(suivant sa complexité, il faudrait ajouter des verrous, etc)
(**) après avoir écrit cet exemple en C, dû à mon passé de développeur
embarqué, je me suis dit: tiens, j'aurais dû faire un exemple en
Javascript (association d'événement "click" à un élément HTML,
puis un window.setTimeout()), je laisse ça en devoir :->
Mon hypothèse est qu'il y a un truc qui tourne sans arrêt pour aller
vérifier l'état des... heu... "interupteurs", mais on me dit que c'est
pas ça (sans me dire ce que c'est)

C'est possible aussi, mais c'est pas efficace du tout. L'OS entier *peut*
être finalement conçu pour générer les appels de fonctions (un peu
moche directement depuis une interruption bas niveau) ou les
événements ci-dessus: il suffit de générer un événement lorsqu'une
interruption matérielle (clavier, souris, etc) est générée.
La plupart des OS modernes ne fonctionnent pas avec du `polling' comme
tu décris mais des interruptions et des files de messages.
Le seul cas récent où j'ai vu du polling pour des événements (à part
des optimisations de lecture de nombreux capteurs, mais c'est hors
sujet) c'est avec le logiciel de "Media center" XBMC (aka Kodi),
c'est d'ailleurs effrayant de voir le CPU qui chauffe :)