Garder les messages les plus récents dans une message queue
7 réponses
rmoyen
Salut,
Un poil de contexte pour expliquer ce que je veux faire et qui me pose
probl=E8me :
J'ai un programme qui tourne (longtemps...) et je veux avoir un
deuxi=E8me programme, diff=E9rent, qui puisse surveiller o=F9 en est le
premier. Pour =E9changer des infos entre ces deux processus totalement
s=E9par=E9s, j'utilise une message queue (comme le deuxi=E8me programme
peut ne pas exister, il me semble que j'aurais du mal =E0 faire ce que
je veux avec un pipe, par exemple).
=C7a marche globalement tr=E8s bien, mon premier programme (cr=E9e et)
remplit (et d=E9truit) la queue, mon deuxi=E8me se connecte dessus et lit
les messages, parfait.
Mais comme le deuxi=E8me programme n'existe pas forc=E9ment, pour =E9viter
que le premier ne bloque quand la queue est pleine, j'=E9cris dans la
queue avec msgsnd(..., IPC_NOWAIT). Du coup, quand la queue est pleine
(si personne ne lit, donc), les derniers messages sont abandonn=E9s et
le programme continue sans perdre de temps.
Le probl=E8me, c'est si le programme surveillant est lanc=E9 alors que le
premier programme tourne depuis un moment : il va se brancher sur le
queue et lire les messages, mais il aura les premiers messages, puis un
grand vide (tous les messages qui ont =E9t=E9 abandonn=E9s parce que la
queue =E9tait pleine), puis les derniers messages (ceux post=E9s depuis
qu'il a commenc=E9 =E0 lire dans la queue). Par exemple, si la queue
contient 5 messages maxi, il aura les messages 1, 2, 3, 4, 5, puis [le
2=E8me prog commence =E0 vider la queue =E0 cet instant] 42, 43, 44, ...
Pour finir, ma question est : existe-t-il un moyen simple de faire en
sorte que, lorsque la queue est pleine, ce soit non pas les messages
les plus r=E9cents, mais les messages les plus anciens, qui soient
abandonn=E9s ? De telle sorte que dans l'exemple pr=E9c=E9dent, le
deuxi=E8me programme lise 37, 38, 39, 40, 41 [d=E9but du 2=E8me prog] 42,
43... ?
J'entrevois vaguement une solution avec une partie du 1er programme
lisant la queue en permanence et s'occuppant de faire le m=E9nage
correctement (peut-=EAtre avec une deuxi=E8me queue), mais =E7a me semble
horriblement compliqu=E9.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Nicolas George
wrote in message :
J'entrevois vaguement une solution avec une partie du 1er programme lisant la queue en permanence et s'occuppant de faire le ménage correctement (peut-être avec une deuxième queue), mais ça me semble horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN, signalant que la queue est pleine, lire un message pour faire de la place.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
rmoyen@gmail.com wrote in message
<1161944431.223959.39730@m73g2000cwd.googlegroups.com>:
J'entrevois vaguement une solution avec une partie du 1er programme
lisant la queue en permanence et s'occuppant de faire le ménage
correctement (peut-être avec une deuxième queue), mais ça me semble
horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN,
signalant que la queue est pleine, lire un message pour faire de la place.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
J'entrevois vaguement une solution avec une partie du 1er programme lisant la queue en permanence et s'occuppant de faire le ménage correctement (peut-être avec une deuxième queue), mais ça me semble horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN, signalant que la queue est pleine, lire un message pour faire de la place.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
rmoyen
Nicolas George wrote:
J'entrevois vaguement une solution avec une partie du 1er programme lisant la queue en permanence et s'occuppant de faire le ménage correctement (peut-être avec une deuxième queue), mais ça me semb le horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN, signalant que la queue est pleine, lire un message pour faire de la place.
Ah oui, bien sûr ! C'est en effet tout simple à implémenter, ça, et y'a pas de raisons que ça ne marche pas.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même si ça faisait longtemps que j'en entendais praler, j'ai commencé à regarder de près toutes ces méthodes de communication il y a quelques jours seulement), un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier processus n'en sait rien. Et pire encore, le lecteur doit pouvoir exister à un moment, puis disparaître, puis être relancé, etc. Il me semble qu'il n'y a guère que les messages queue qui me permettent de faire ça ?
En tout cas, merci pour ta suggestion ! -- Rémi Moyen
Nicolas George wrote:
J'entrevois vaguement une solution avec une partie du 1er programme
lisant la queue en permanence et s'occuppant de faire le ménage
correctement (peut-être avec une deuxième queue), mais ça me semb le
horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN,
signalant que la queue est pleine, lire un message pour faire de la place.
Ah oui, bien sûr ! C'est en effet tout simple à implémenter, ça, et
y'a pas de raisons que ça ne marche pas.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même
si ça faisait longtemps que j'en entendais praler, j'ai commencé à
regarder de près toutes ces méthodes de communication il y a quelques
jours seulement), un processus qui écrit dans une FIFO bloque si il
n'y a personne qui lit à l'autre bout, non ?
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier
processus n'en sait rien. Et pire encore, le lecteur doit pouvoir
exister à un moment, puis disparaître, puis être relancé, etc. Il
me semble qu'il n'y a guère que les messages queue qui me permettent
de faire ça ?
En tout cas, merci pour ta suggestion !
--
Rémi Moyen
J'entrevois vaguement une solution avec une partie du 1er programme lisant la queue en permanence et s'occuppant de faire le ménage correctement (peut-être avec une deuxième queue), mais ça me semb le horriblement compliqué.
On peut faire ça en beaucoup plus simple : si msgsend renvoie EAGAIN, signalant que la queue est pleine, lire un message pour faire de la place.
Ah oui, bien sûr ! C'est en effet tout simple à implémenter, ça, et y'a pas de raisons que ça ne marche pas.
D'ailleurs, tu dois pouvoir faire la même chose avec un FIFO.
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même si ça faisait longtemps que j'en entendais praler, j'ai commencé à regarder de près toutes ces méthodes de communication il y a quelques jours seulement), un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier processus n'en sait rien. Et pire encore, le lecteur doit pouvoir exister à un moment, puis disparaître, puis être relancé, etc. Il me semble qu'il n'y a guère que les messages queue qui me permettent de faire ça ?
En tout cas, merci pour ta suggestion ! -- Rémi Moyen
Thierry Boudet
On 2006-10-27, wrote:
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier processus n'en sait rien. Et pire encore, le lecteur doit pouvoir exister à un moment, puis disparaître, puis être relancé, etc. Il me semble qu'il n'y a guère que les messages queue qui me permettent de faire ça ?
J'ai pas tout suivi, mais il me semble qu'un process qui reçoit
ces divers messages et gère un buffer circulaire en shared mem pourrait être une solution...
--
La photo argentique n'est pas morte ? elle existe en 64 bits ? ;-) Depuis que le 25 bits est mort et enterré...
On 2006-10-27, rmoyen@gmail.com <rmoyen@gmail.com> wrote:
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier
processus n'en sait rien. Et pire encore, le lecteur doit pouvoir
exister à un moment, puis disparaître, puis être relancé, etc. Il
me semble qu'il n'y a guère que les messages queue qui me permettent
de faire ça ?
J'ai pas tout suivi, mais il me semble qu'un process qui reçoit
ces divers messages et gère un buffer circulaire en shared mem
pourrait être une solution...
--
La photo argentique n'est pas morte ? elle existe en 64 bits ?
;-) Depuis que le 25 bits est mort et enterré...
Dans mon cas, le processus "lecteur" peut exister ou pas, le premier processus n'en sait rien. Et pire encore, le lecteur doit pouvoir exister à un moment, puis disparaître, puis être relancé, etc. Il me semble qu'il n'y a guère que les messages queue qui me permettent de faire ça ?
J'ai pas tout suivi, mais il me semble qu'un process qui reçoit
ces divers messages et gère un buffer circulaire en shared mem pourrait être une solution...
--
La photo argentique n'est pas morte ? elle existe en 64 bits ? ;-) Depuis que le 25 bits est mort et enterré...
lhabert
:
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas bloquer sur le open.
rmoyen@gmail.com :
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à
l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux
directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas
bloquer sur le open.
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas bloquer sur le open.
rmoyen
Luc Habert wrote:
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas bloquer sur le open.
Ah oui, j'avais raté ça dans le man. Bon, ceci dit, maintenant que j'ai tout implémenté avec des message queue (et que ça a l'air de tout marcher), à moins que je ne tombe sur une très grosse raison de changer d'implémentation, je vais m'en tenir là.
D'autant plus que la notion de communication par petits messages, chacun d'un type précis, me semble plus adaptée à ce que je veux échanger entre les processus qu'un flux d'infos plus ou moins continu (type FIFO) -- même si je pourrais évidemment m'en accomoder aussi, si il fallait.
Merci quand même ! -- Rémi Moyen
Luc Habert wrote:
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à
l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux
directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas
bloquer sur le open.
Ah oui, j'avais raté ça dans le man. Bon, ceci dit, maintenant que
j'ai tout implémenté avec des message queue (et que ça a l'air de
tout marcher), à moins que je ne tombe sur une très grosse raison de
changer d'implémentation, je vais m'en tenir là.
D'autant plus que la notion de communication par petits messages,
chacun d'un type précis, me semble plus adaptée à ce que je veux
échanger entre les processus qu'un flux d'infos plus ou moins continu
(type FIFO) -- même si je pourrais évidemment m'en accomoder aussi,
si il fallait.
un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Tu peux le passer en mode non-bloquant avec fcntl. En fait, tu veux directement l'ouvrir en mode non-bloquant (O_NONBLOCK), histoire de ne pas bloquer sur le open.
Ah oui, j'avais raté ça dans le man. Bon, ceci dit, maintenant que j'ai tout implémenté avec des message queue (et que ça a l'air de tout marcher), à moins que je ne tombe sur une très grosse raison de changer d'implémentation, je vais m'en tenir là.
D'autant plus que la notion de communication par petits messages, chacun d'un type précis, me semble plus adaptée à ce que je veux échanger entre les processus qu'un flux d'infos plus ou moins continu (type FIFO) -- même si je pourrais évidemment m'en accomoder aussi, si il fallait.
Merci quand même ! -- Rémi Moyen
Nicolas George
wrote in message :
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même si ça faisait longtemps que j'en entendais praler, j'ai commencé à regarder de près toutes ces méthodes de communication il y a quelques jours seulement), un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Ce n'est pas exactement ça. D'une part, tu vas bloquer à l'ouverture du FIFO s'il n'y a pas de lecteur, mais tu peux éviter ça soit en ouvrant en non-bloquant, soit en ouvrant en lecture-écriture. Si tu comptes appliquer la politique de lire quand il n'y a plus de place, alors cette dernière solution convient très bien.
D'autre part, si tu tentes d'écrire alors qu'il n'y a pas de lecteur, tu vas te prendre un SIGPIPE. Mais là encore, si tu as ouvert en lecture-écriture, ce n'est pas un problème.
Enfin, si tu tentes d'écrire alors qu'aucun lecteur ne lit effectivement, tu vas te retrouver bloqué, mais ça s'évite en mettant en non-bloquant. Et surtout, tu as la garantie d'avoir un buffer d'au moins PIPE_BUF, qui vaut au moins 512.
La difficulté avec cette méthode, c'est l'atomicité des lectures : si tu as deux processus qui lisent en même temps (typiquement, l'écriveur qui veut faire de la place, et le vrai lecteur qui vient d'être lancé), et des messages qui font plus d'un octet, tu n'as aucune garantie que le découpage des lectures tombe sur des limites de messages. Ça peut se corriger avec un verrou. Sous certains Unix, on peut verrouiller un pipe, je ne sais pas à quel point c'est standard.
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messages : j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue, et très mal intégrée au système Unix. Un pipe, au moins, peut être multiplexé avec select ou poll, passé sur un file descriptor, etc.
rmoyen@gmail.com wrote in message
<1161951613.854753.25020@b28g2000cwb.googlegroups.com>:
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même
si ça faisait longtemps que j'en entendais praler, j'ai commencé à
regarder de près toutes ces méthodes de communication il y a quelques
jours seulement), un processus qui écrit dans une FIFO bloque si il
n'y a personne qui lit à l'autre bout, non ?
Ce n'est pas exactement ça. D'une part, tu vas bloquer à l'ouverture du FIFO
s'il n'y a pas de lecteur, mais tu peux éviter ça soit en ouvrant en
non-bloquant, soit en ouvrant en lecture-écriture. Si tu comptes appliquer
la politique de lire quand il n'y a plus de place, alors cette dernière
solution convient très bien.
D'autre part, si tu tentes d'écrire alors qu'il n'y a pas de lecteur, tu vas
te prendre un SIGPIPE. Mais là encore, si tu as ouvert en lecture-écriture,
ce n'est pas un problème.
Enfin, si tu tentes d'écrire alors qu'aucun lecteur ne lit effectivement, tu
vas te retrouver bloqué, mais ça s'évite en mettant en non-bloquant. Et
surtout, tu as la garantie d'avoir un buffer d'au moins PIPE_BUF, qui vaut
au moins 512.
La difficulté avec cette méthode, c'est l'atomicité des lectures : si tu as
deux processus qui lisent en même temps (typiquement, l'écriveur qui veut
faire de la place, et le vrai lecteur qui vient d'être lancé), et des
messages qui font plus d'un octet, tu n'as aucune garantie que le découpage
des lectures tombe sur des limites de messages. Ça peut se corriger avec un
verrou. Sous certains Unix, on peut verrouiller un pipe, je ne sais pas à
quel point c'est standard.
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messages :
j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue,
et très mal intégrée au système Unix. Un pipe, au moins, peut être
multiplexé avec select ou poll, passé sur un file descriptor, etc.
Ben, si j'ai bien compris ce que j'ai lu (j'avoue sans honte que, même si ça faisait longtemps que j'en entendais praler, j'ai commencé à regarder de près toutes ces méthodes de communication il y a quelques jours seulement), un processus qui écrit dans une FIFO bloque si il n'y a personne qui lit à l'autre bout, non ?
Ce n'est pas exactement ça. D'une part, tu vas bloquer à l'ouverture du FIFO s'il n'y a pas de lecteur, mais tu peux éviter ça soit en ouvrant en non-bloquant, soit en ouvrant en lecture-écriture. Si tu comptes appliquer la politique de lire quand il n'y a plus de place, alors cette dernière solution convient très bien.
D'autre part, si tu tentes d'écrire alors qu'il n'y a pas de lecteur, tu vas te prendre un SIGPIPE. Mais là encore, si tu as ouvert en lecture-écriture, ce n'est pas un problème.
Enfin, si tu tentes d'écrire alors qu'aucun lecteur ne lit effectivement, tu vas te retrouver bloqué, mais ça s'évite en mettant en non-bloquant. Et surtout, tu as la garantie d'avoir un buffer d'au moins PIPE_BUF, qui vaut au moins 512.
La difficulté avec cette méthode, c'est l'atomicité des lectures : si tu as deux processus qui lisent en même temps (typiquement, l'écriveur qui veut faire de la place, et le vrai lecteur qui vient d'être lancé), et des messages qui font plus d'un octet, tu n'as aucune garantie que le découpage des lectures tombe sur des limites de messages. Ça peut se corriger avec un verrou. Sous certains Unix, on peut verrouiller un pipe, je ne sais pas à quel point c'est standard.
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messages : j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue, et très mal intégrée au système Unix. Un pipe, au moins, peut être multiplexé avec select ou poll, passé sur un file descriptor, etc.
rmoyen
Nicolas George wrote:
[snip explications sur les FIFOs]
Je crois que je comprends ce que tu veux dire, je n'avais pas fouillé cette piste en détail.
La difficulté avec cette méthode, c'est l'atomicité des lectures [snip]
Ah oui, en effet...
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messa ges : j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue, et très mal intégrée au système Unix. Un pipe, au moins, peut ê tre multiplexé avec select ou poll, passé sur un file descriptor, etc.
Euh... je suis un peu perdu, là. J'ai jamais utilisé (ni regardé de près !) select/poll...
Enfin, dans les limites de ce dont j'ai besoin, ça ne me semble pas vraiment génant. Et, comme je le disais ailleurs, j'ai le sentiment qu'une queue a une structure plus adaptée au type d'infos que je veux tranférer (des messages et non pas un flux plus ou moins continu).
Merci pour tes explications ! -- Rémi Moyen
Nicolas George wrote:
[snip explications sur les FIFOs]
Je crois que je comprends ce que tu veux dire, je n'avais pas fouillé
cette piste en détail.
La difficulté avec cette méthode, c'est l'atomicité des lectures
[snip]
Ah oui, en effet...
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messa ges :
j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue,
et très mal intégrée au système Unix. Un pipe, au moins, peut ê tre
multiplexé avec select ou poll, passé sur un file descriptor, etc.
Euh... je suis un peu perdu, là. J'ai jamais utilisé (ni regardé de
près !) select/poll...
Enfin, dans les limites de ce dont j'ai besoin, ça ne me semble pas
vraiment génant. Et, comme je le disais ailleurs, j'ai le sentiment
qu'une queue a une structure plus adaptée au type d'infos que je veux
tranférer (des messages et non pas un flux plus ou moins continu).
Je crois que je comprends ce que tu veux dire, je n'avais pas fouillé cette piste en détail.
La difficulté avec cette méthode, c'est l'atomicité des lectures [snip]
Ah oui, en effet...
Concernant l'intérêt d'utiliser un pipe plutôt qu'une file de messa ges : j'ai toujours trouvé que l'API des IPC SysV était vraiment très mal conçue, et très mal intégrée au système Unix. Un pipe, au moins, peut ê tre multiplexé avec select ou poll, passé sur un file descriptor, etc.
Euh... je suis un peu perdu, là. J'ai jamais utilisé (ni regardé de près !) select/poll...
Enfin, dans les limites de ce dont j'ai besoin, ça ne me semble pas vraiment génant. Et, comme je le disais ailleurs, j'ai le sentiment qu'une queue a une structure plus adaptée au type d'infos que je veux tranférer (des messages et non pas un flux plus ou moins continu).