OVH Cloud OVH Cloud

Lecture bloquante de FIFO

15 réponses
Avatar
Nicolas HUYNH
Bonjour à tous

Existe-t-il un moyen simple d'écrire un thread en C ou C++
qui attende des éléments sur une FIFO (une queue STL par exemple)
*sans faire d'attente active* (même avec une temporisation) ?

Concrètement, je ne souhaite pas de :

while (true) {
if (!queue->empty()) {
element = queue->front();
...
queue->pop();
}
/* éventuellement une temporisation ici */
}

mais plutôt un appel bloquant "à la langage Ada"

Merci pour toute réponse !

N.

5 réponses

1 2
Avatar
Christophe de VIENNE
Bertrand Motuelle wrote:

Comme tu le dis, l'héritage privé dans ce cas n'est pas génial (je trouve
qu'ici ca ne fait que compliquer la lecture du code).



C'est ce que je me suis dit à la relecture au moment du post. Je ferais
surement une autre version quand j'aurais un peu de temps pour faire des
exercices de styles.


namespace cvtools {

template <class Queue>
struct not_empty {
Queue & q;
not_empty(Queue & q): q(q) {};
bool operator()() {
return ! q.empty();
}
};


Pourquoi ne pas utiliser les const ci-dessus ?


C'est un tort, j'aurais du.

[snip declaration de la sync_queue]
Personellement, j'aurais plutôt tendance à mettre les fonctions publiques
avant la section privée.


Oui, je fais plutot ça maintenant mais quand je l'ai écrit j'avais
encore tendance à faire selon mon humeur :-)

Je déclarerais empty() et size() const, et my_mutex et my_condition mutable.


J'ai mieux cerné l'utilité du mutable dans de tels cas depuis lors. Ce
sera surement dans la prochaine version...

Et puis, ben je supprimerais l'héritage et déclarerais my_queue ;-)



Je suis d'accord.

[snip surchages my_pop()]


C'est marrant, j'ai l'impression d'avoir dejà vu ca dans un de tes messages
ici, il y a quelques mois :-)



Pas mal :-)


[snip push]

C'est pinailler, mais le mutex peut être relaché avant l'appel notify_one()
(dans le cas général).



A oui tiens... J'y penserais.


}



[snip surcharges de pop()]

Puisque tu demandais des commentaires sur le style: l'idiome avec les
variables conditionnelles est plutôt d'utiliser un while sur la condition
(les threads bloqués peuvent souffrir de "spurious wakeup").
Je trouves que la solution que tu as retenue (le wait + prédicat, qui cache
le while) est beaucoup moins lisible (combinée avec l'héritage privé, il m'a
fallu quelque retours arrières + avances rapides avant de voir quelle
fonction empty() était réelement appelée).


Si je me souviens bien, j'avais commencé par un while, qui s'est
transformé en wait + prédicat lorsque je me suis rendu compte que boost
le proposait. Et là forcément je me suis dit : "Wouaaah, c'est vachement
c++ ça"... D'où l'adoption du bazar. Mais tu as raison de dire que c'est
moins lisible. J'imagine que dans certains cas ça peut être plus
interessant mais pas quand c'est aussi simple (à la limite c'est presque
de l'obfuscation).


[snip implementation pop()]


Enfin, je n'aurais pas essayé de coller les deux wait/timed_wait dans la
même fonction pop.
Je trouve que garder deux fonctions séparées n'a que des avantages
(lisibilité, pas de création de variable inutile dans le cas du wait...)


En effet, en plus ça pourrait s'averer coûteux de tout le temps faire un
boost::xtime_get sur un simple wait dans le cas d'une charge un peu
importante.


[snip empty(), size()]

Et sinon, je ne peux qu'être d'accord avec ton implémentation: mis à part 2
ou 3 détails c'est vraiment comme ca que je fais :-)
(mais sans boost, un de mes compilos y est allergique).



Merci pour tes remarques !


A+

Christophe


Avatar
kanze
Emmanuel Delahaye wrote in message
news:...
In 'fr.comp.lang.c', Nicolas HUYNH wrote:

Existe-t-il un moyen simple d'écrire un thread en C ou C++


Il n'y a pas de thread en C. C'est une ressource système. Merci de
reposter sur un forum dédié à ton système.


Il y a néaumoins des solutions portables, par exemple Boost, dont la
discussion est tout à fait acceptable ici.

Je crois que boost::condition, c'est exactement ce qu'il lui faut.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Erwan David
écrivait :

Emmanuel Delahaye wrote in message
news:...
In 'fr.comp.lang.c', Nicolas HUYNH wrote:

Existe-t-il un moyen simple d'écrire un thread en C ou C++


Il n'y a pas de thread en C. C'est une ressource système. Merci de
reposter sur un forum dédié à ton système.


Il y a néaumoins des solutions portables, par exemple Boost, dont la
discussion est tout à fait acceptable ici.


Bah non, il y a 2 ici

Je crois que boost::condition, c'est exactement ce qu'il lui faut.


Et là c'est calirement hors sujet dans fr.comp.lang.c

Suite dans c++ seulement



Avatar
kanze
Erwan David wrote in message
news:...
écrivait :

Emmanuel Delahaye wrote in message
news:...
In 'fr.comp.lang.c', Nicolas HUYNH wrote:

Existe-t-il un moyen simple d'écrire un thread en C ou C++


Il n'y a pas de thread en C. C'est une ressource système. Merci de
reposter sur un forum dédié à ton système.


Il y a néaumoins des solutions portables, par exemple Boost, dont la
discussion est tout à fait acceptable ici.


Bah non, il y a 2 ici


Effectivement. Je n'avais pas régardé la ligne des groupes. Pour moi,
ici, c'était fr.comp.lang.c++.

Je crois que boost::condition, c'est exactement ce qu'il lui faut.


Et là c'est calirement hors sujet dans fr.comp.lang.c


Tout à fait. Mes excuses.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16




Avatar
Nicolas HUYNH
Nicolas HUYNH wrote:
Bonjour à tous

Existe-t-il un moyen simple d'écrire un thread en C ou C++
qui attende des éléments sur une FIFO (une queue STL par exemple)
*sans faire d'attente active* (même avec une temporisation) ?

Concrètement, je ne souhaite pas de :

while (true) {
if (!queue->empty()) {
element = queue->front();
...
queue->pop();
}
/* éventuellement une temporisation ici */
}

mais plutôt un appel bloquant "à la langage Ada"



Merci à tous pour vos réponses qui vont sans doute
me dépanner.
Je vais tester cela !

N.

1 2