Avertir un ensemble de process que quelquechose se passe
20 réponses
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.
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
rixed@apc.happyleptic.org 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
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
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...
On 2008-12-18, Michel Talon <talon@lpthe.jussieu.fr> 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...
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...
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
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.
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
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.
On 2008-12-18, rixed@apc.happyleptic.org <rixed@apc.happyleptic.org> 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.
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
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.
Michel Talon wrote in message <gids24$86i$1@asmodee.lpthe.jussieu.fr>:
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.
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.
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
Nicolas George <nicolas$george@salle-s.org> wrote:
Michel Talon wrote in message <gids24$86i$1@asmodee.lpthe.jussieu.fr>:
> 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 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
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
Nicolas George <nicolas$george@salle-s.org> wrote:
Michel Talon wrote in message <gids24$86i$1@asmodee.lpthe.jussieu.fr>:
> 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 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
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.
Michel Talon wrote in message <giepc6$hju$1@asmodee.lpthe.jussieu.fr>:
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.
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.
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.
On 2008-12-19, Michel Talon <talon@lpthe.jussieu.fr> wrote:
Nicolas George <nicolas$george@salle-s.org> wrote:
Michel Talon wrote in message <gids24$86i$1@asmodee.lpthe.jussieu.fr>:
> 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.
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.