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

Avertir un ensemble de process que quelquechose se passe

20 réponses
Avatar
rixed
Bonjour !

J'ai un problème de synchronisation dont je ne trouve pas de solution
simple. Voilà :

J'ai un process producteur qui, de temps en temps, modifie des fichiers.

J'ai aussi, en option, quelques process consommateurs qui font des
choses avec les fichiers produits par ce premier process. Même si celui-ci
n'est pas lancé, d'ailleurs.

J'aimerais que le producteur, lorsqu'il tourne et qu'il vient de changer
ses fichiers, avertisse les autres que quelquechose à changé et qu'ils
doivent se mettre au travail.

Actuellement, les consommateurs jettent un oeil toutes les secondes sur
les fichiers du producteur pour voir s'il y a du neuf, mais ce n'est pas
optimal...

L'ennuis, c'est que tous ses process peuvent être lancés / arrétés
n'importe quand et indépendamment. Je ne trouve donc pas de solution
simple à base de signal. Je ne trouve pas non plus mon bonheur du côté
des files de messages ni des sémaphores, et l'horrible famd me fait
peur.

La seule chose que je vois c'est que chaque consommateur s'enregistre
auprès du producteur (s'il est lancé, sinon essayer régulièrement...)
pour recevoir une notification, par exemple via une socket. Mais
je rève de quelquechose de plus simple, permettant au producteur de
"broadcaster" un signal quelconque à destination de consommateurs
éventuels ; genre quelquechose de similaire au netlink broadcast de
Linux.

Avez-vous des idées ?

10 réponses

1 2
Avatar
talon
wrote:
La seule chose que je vois c'est que chaque consommateur s'enregistre
auprès du producteur (s'il est lancé, sinon essayer régulièrement...)
pour recevoir une notification, par exemple via une socket. Mais
je rève de quelquechose de plus simple, permettant au producteur de
"broadcaster" un signal quelconque à destination de consommateurs
éventuels ; genre quelquechose de similaire au netlink broadcast de
Linux.

Avez-vous des idées ?




select, poll, epoll, kqueue, ... selon le cas. Le consommateur (ou un
thread du consommateur) restant en attente sur un tel "select" qui
regarde s'il y a des choses à lire sur la sortie du producteur.
Voir par exemple le "tail -f" de freebsd et notamment les fonctions
set_events() et follow() dans
http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/tail/forward.c


--

Michel TALON
Avatar
rixed
On 2008-12-18, Michel Talon wrote:
select, poll, epoll, kqueue, ... selon le cas. Le consommateur (ou un
thread du consommateur) restant en attente sur un tel "select" qui
regarde s'il y a des choses à lire sur la sortie du producteur.



Cela implique que le producteur ajoute au moins un octet à la fin d'un
fichier (celui qui est "selecté()" par les consommateurs) chaque fois
qu'il veut avertir ses éventuels clients... N'y a t-il pas un moyen sans
écrire dans un vrai fichier ?

Remarque, je peut toujours dire que le fichier est "vidé" par le
producteur au bout d'une taille prédéfinie connue aussi des consommateurs
(genre quelques centaines d'octets). Lorsqu'ils arrivent à la fin les
consommateurs se positionnent au début et attendent que le fichier se
fasse vider (ie. ils attendent que le read() bloque... Hum, ça m'a pas
l'air faisable ça...)

Ca n'existe pas des pipes nommés que plusieurs process peuvent lire
ensemble ? Non je suppose, il faut bien dans ce cas stoquer les
écritures quelquepart...
Avatar
rixed
Je viens de me rendre compte que j'ai raisonné comme une cloche et écrit
n'importe quoi. A la fin d'un fichier il y a toujours la fin de fichier
à lire.

Bon je vais regarder comment fait tail -f
Avatar
rixed
On 2008-12-18, wrote:
Bon je vais regarder comment fait tail -f



Bon, pas de magie à l'horizon : ça sleep() oubien ça utilise une API
spécifique au kernel.
Avatar
talon
wrote:
On 2008-12-18, wrote:
> Bon je vais regarder comment fait tail -f

Bon, pas de magie à l'horizon : ça sleep() oubien ça utilise une API
spécifique au kernel.




Justement, ça sleep ou ça utilise un truc genre select, etc.

--

Michel TALON
Avatar
Nicolas George
Michel Talon wrote in message <gids24$86i$:
Justement, ça sleep ou ça utilise un truc genre select, etc.



select ne marche pas sur les fichiers réguliers. Pour surveiller les
fichiers réguliers, il n'y a pas d'API Unix standard. fam est justement ce
qui wrappe les API spécifiques à chaque OS, mais c'est une bouze.
Avatar
talon
Nicolas George <nicolas$ wrote:
Michel Talon wrote in message <gids24$86i$:
> Justement, ça sleep ou ça utilise un truc genre select, etc.

select ne marche pas sur les fichiers réguliers. Pour surveiller les
fichiers réguliers, il n'y a pas d'API Unix standard. fam est justement ce
qui wrappe les API spécifiques à chaque OS, mais c'est une bouze.



Tiens mon expérience ne va pas jusque là! Dans la version python dont
j'ai plus l'habitude (et où j'ai utilisé cette technique) il y a
os.select() utilisable sur les fichiers sur tout Unix, mais pas Windows
(ce dernier cas je m'en fous complètement). Voici la référence:
http://docs.python.org/library/select.html
Je remarque d'ailleurs que python a maintenant des wrappers standards
pour le epoll de Linux et le kqueue de FreeBSD.

Celà étant, sur ma machine le service de surveillance des fichiers pour
KDE st fourni par gamin (et non pas fam) et je n'ai pas remarqué que ça
pose de problème (j'en ai eu au contraire autrefois avec fam).

--

Michel TALON
Avatar
talon
Nicolas George <nicolas$ wrote:
Michel Talon wrote in message <gids24$86i$:
> Justement, ça sleep ou ça utilise un truc genre select, etc.

select ne marche pas sur les fichiers réguliers. Pour surveiller les
fichiers réguliers, il n'y a pas d'API Unix standard. fam est justement ce
qui wrappe les API spécifiques à chaque OS, mais c'est une bouze.



Poll et select peuvent être utilisés pour savoir s'il y a quelque chose
à lire sur un fichier régulier, donc il suffit que le producteur écrive
sur un fichier auxiliaire dès qu'il a rempli le fichier principal, et
que le consommateur vide le fichier auxiliaire avant de traîter le
fichier principal. Ainsi le problème de surveiller l'allongement du
fichier principal ne se pose pas. Il se trouve que le kqueue de *BSD
peut surveiller l'allongement d'un fichier.

Il y a de toute façon bien plus simple et évident avec des threads posix
et l'utilisation des variables de condition pour gérer un modèle
producteur consommateurs (voir Butenhof). Les threads consommateurs
peuvent d'ailleurs faire un fork() et un wait() si on veut mordicus
avoir des processus indépendants.

--

Michel TALON
Avatar
Nicolas George
Michel Talon wrote in message <giepc6$hju$:
Poll et select peuvent être utilisés pour savoir s'il y a quelque chose
à lire sur un fichier régulier



Non. Je cite la norme :

# File descriptors associated with regular files shall always select true for
# ready to read, ready to write, and error conditions.

Résumé : sur un fichier régulier, ça dit toujours oui tout de suit. Pas très
utile.

Il y a de toute façon bien plus simple et évident avec des threads posix
et l'utilisation des variables de condition pour gérer un modèle
producteur consommateurs (voir Butenhof).



À condition que les producteurs et consommateurs soient apparentés dans la
hiérarchie des process, ce qui ne semble pas être le cas ici.

Les threads consommateurs
peuvent d'ailleurs faire un fork() et un wait() si on veut mordicus
avoir des processus indépendants.



Aucune garantie que les fonctions sur les threads marchent après un fork.
Avatar
rixed
On 2008-12-19, Michel Talon wrote:
Nicolas George <nicolas$ wrote:
Michel Talon wrote in message <gids24$86i$:
> Justement, ça sleep ou ça utilise un truc genre select, etc.



Poll et select peuvent être utilisés pour savoir s'il y a quelque chose
à lire sur un fichier régulier



Il y a des cas ou read() bloque sur un fichier régulier ?

Il y a de toute façon bien plus simple et évident avec des threads posix
et l'utilisation des variables de condition pour gérer un modèle
producteur consommateurs (voir Butenhof).



Ce serait bien plus simple si je pouvait imposer que le lancement des
process ne soit pas indépendant, mais ici ce n'est pas possible : ils
doivent tous pouvoir démarrer, s'arreter et redémarrer n'importe quand.
1 2