Boost / Threads / Mutex

9 réponses
Avatar
Gégé
Hello,

Je suis en train d'impl=E9menter un serveur qui re=E7oit des requ=EAtes
clientes. J'aimerais imposer un nombre de requ=EAtes =E0 traiter
simultan=E9ment, les autres =E9tant plac=E9es en file d'attente.

Pour un traitement client par client, pas de souci, j'utilise un mutex
qui prot=E8ge ma ressource (ici mon traitement). En revanche, si je veux
traiter par lot de clients (c'est =E0 dire au fil de l'arriv=E9e des
requ=EAtes, mais avec au plus n threads r=E9ellement actifs), je ne vois
pas comment faire.

Auriez-vous une id=E9e svp ? Merci

ps: J'utilise boost

9 réponses

Avatar
Gégé
On 3 jan, 16:22, Gégé wrote:
Hello,

Je suis en train d'implémenter un serveur qui reçoit des requêtes
clientes. J'aimerais imposer un nombre de requêtes à traiter
simultanément, les autres étant placées en file d'attente.

Pour un traitement client par client, pas de souci, j'utilise un mutex
qui protège ma ressource (ici mon traitement). En revanche, si je veux
traiter par lot de clients (c'est à dire au fil de l'arrivée des
requêtes, mais avec au plus n threads réellement actifs), je ne vois
pas comment faire.

Auriez-vous une idée svp ? Merci

ps: J'utilise boost



En utilisant un nombre fixe de mutex (ici 2) , j'aurai ceci :

int count;
boost::mutex io_m;
boost::mutex m1;
boost::mutex m2;

void my_sub( int i )
{
int mutex_id = 0;

boost::unique_lock<boost::mutex> L1( m1 );
boost::unique_lock<boost::mutex> L2( m2, boost::try_to_lock );
++count;

if( L2.owns_lock() )
{
L1.unlock();
mutex_id = 2;
}
else
{
mutex_id = 1;
}

Sleep( 1000 );

boost::lock_guard<boost::mutex> L( io_m );
std::cout << "thread #" << i << ", mutex #" << mutex_id << ",
count=" << count << std::endl;
--count;
}


int main(int argc, char** argv)
{

count = 0;
boost::thread_group G;

for( int i = 0; i < 10; i++ )
{
G.create_thread( boost::bind( &my_sub, i ) );
}

G.join_all();

sys::pause();
return 0;
}
Avatar
Antonio
Bonjour,

Et bien moi je ferai une "queue" (exercice classique avec
mutex/condition) de tâches à réaliser, et un "boost::thread_group"
qui aurait des threads qui piochent dans cette queue pour exécuter les
tâches en attente.

A+


Le 03/01/2012 16:22, Gégé a écrit :
Hello,

Je suis en train d'implémenter un serveur qui reçoit des requêtes
clientes. J'aimerais imposer un nombre de requêtes à traiter
simultanément, les autres étant placées en file d'attente.

Pour un traitement client par client, pas de souci, j'utilise un mutex
qui protège ma ressource (ici mon traitement). En revanche, si je veux
traiter par lot de clients (c'est à dire au fil de l'arrivée des
requêtes, mais avec au plus n threads réellement actifs), je ne vois
pas comment faire.

Auriez-vous une idée svp ? Merci

ps: J'utilise boost
Avatar
Gégé
On 4 jan, 09:47, Antonio wrote:
Bonjour,

Et bien moi je ferai une "queue" (exercice classique avec
mutex/condition) de tâches à réaliser, et un "boost::thread_group"
qui aurait des threads qui piochent dans cette queue pour exécuter les
tâches en attente.

A+

Le 03/01/2012 16:22, Gégé a écrit :







> Hello,

> Je suis en train d'implémenter un serveur qui reçoit des requêtes
> clientes. J'aimerais imposer un nombre de requêtes à traiter
> simultanément, les autres étant placées en file d'attente.

> Pour un traitement client par client, pas de souci, j'utilise un mutex
> qui protège ma ressource (ici mon traitement). En revanche, si je veu x
> traiter par lot de clients (c'est à dire au fil de l'arrivée des
> requêtes, mais avec au plus n threads réellement actifs), je ne voi s
> pas comment faire.

> Auriez-vous une idée svp ? Merci

> ps: J'utilise boost



Je ne suis pas trop familier avec les conditions. Est-ce que tu veux
parler de qq chose comme ca ?
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe -queue-using-condition-variables.html
Avatar
Antonio
Le 04/01/2012 22:55, Gégé a écrit :
On 4 jan, 09:47, Antonio wrote:
Bonjour,

Et bien moi je ferai une "queue" (exercice classique avec
mutex/condition) de tâches à réaliser, et un "boost::thread_group"
qui aurait des threads qui piochent dans cette queue pour exécuter les
tâches en attente.

A+

Le 03/01/2012 16:22, Gégé a écrit :







Hello,



Je suis en train d'implémenter un serveur qui reçoit des requêtes
clientes. J'aimerais imposer un nombre de requêtes à traiter
simultanément, les autres étant placées en file d'attente.



Pour un traitement client par client, pas de souci, j'utilise un mutex
qui protège ma ressource (ici mon traitement). En revanche, si je veux
traiter par lot de clients (c'est à dire au fil de l'arrivée des
requêtes, mais avec au plus n threads réellement actifs), je ne vois
pas comment faire.



Auriez-vous une idée svp ? Merci



ps: J'utilise boost





Je ne suis pas trop familier avec les conditions. Est-ce que tu veux
parler de qq chose comme ca ?
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html



Oui, c'est bien ça. L'idée c'est que les requêtes sont "push"ées (appel
non bloquant) dans la queue, puis un nb déterminé de threads dans un
"thread_group" effectuent toutes un "pop" (appel bloquant, typiquement
dans une boucle) sur cette queue pour en extraire les requêtes. Si une
seule requête arrive, une seule thread sera débloquée et traitera cette
requête. Si "n" requêtes arrivent, les threads se débloqueront au fur et
à mesure, éventuellement des requêtes seront en attente si toutes les
threads sont déjà occupées.
Moyennant adaptation (dérivation) il est possible d'adapter le nb de
threads du "thread_group" pour adapter dynamiquement le nb de threads à
la charge.

A+
Avatar
Jean-Marc Desperrier
Antonio a écrit :
Et bien moi je ferai une "queue" (exercice classique avec
mutex/condition) de tâches à réaliser, et un "boost::thread_group"
qui aurait des threads qui piochent dans cette queue pour exécuter les
tâches en attente.



N'est-ce pas un grosse erreur de perdre son temps à réécrire la 200ème
implémentation de cela ?

Il y a un certain temps, j'avais sélectionné celle-ci
http://threadpool.sourceforge.net/tutorial/intro.html (elle fait
*exactement* ce que tu décris 2 message plus bas, et à peu près rien de
plus), elle ne contient pas énormément de code, elle ajoute juste le
minimum qu'il faut à boost, mais est écrite plutôt proprement et
efficacement, et j'ai été assez satisfait du choix.
Il y a peut-être mieux aujourd'hui
Avatar
Antonio
Le 05/01/2012 12:11, Jean-Marc Desperrier a écrit :
Antonio a écrit :
Et bien moi je ferai une "queue" (exercice classique avec
mutex/condition) de tâches à réaliser, et un "boost::thread_group"
qui aurait des threads qui piochent dans cette queue pour exécuter les
tâches en attente.



N'est-ce pas un grosse erreur de perdre son temps à réécrire la 200ème
implémentation de cela ?

Il y a un certain temps, j'avais sélectionné celle-ci
http://threadpool.sourceforge.net/tutorial/intro.html (elle fait
*exactement* ce que tu décris 2 message plus bas, et à peu près rien de
plus), elle ne contient pas énormément de code, elle ajoute juste le
minimum qu'il faut à boost, mais est écrite plutôt proprement et
efficacement, et j'ai été assez satisfait du choix.
Il y a peut-être mieux aujourd'hui



Il ne s'agit pas de récrire mais d'apprendre lorsqu'on débute ou que
l'on commence un peu à maitriser les choses.
Ensuite, avec l'expérience, il faut réutiliser ce qui existe pour ne pas
perdre son temps, je suis bien d'accord!
Avatar
Gégé
On 5 jan, 13:15, Antonio wrote:
Le 05/01/2012 12:11, Jean-Marc Desperrier a écrit :









> Antonio a écrit :
>> Et bien moi je ferai une "queue" (exercice classique avec
>> mutex/condition) de tâches à réaliser, et un "boost::thread_grou p"
>> qui aurait des threads qui piochent dans cette queue pour exécuter l es
>> tâches en attente.

> N'est-ce pas un grosse erreur de perdre son temps à réécrire la 2 00ème
> implémentation de cela ?

> Il y a un certain temps, j'avais sélectionné celle-ci
>http://threadpool.sourceforge.net/tutorial/intro.html(elle fait
> *exactement* ce que tu décris 2 message plus bas, et à peu près r ien de
> plus), elle ne contient pas énormément de code, elle ajoute juste l e
> minimum qu'il faut à boost, mais est écrite plutôt proprement et
> efficacement, et j'ai été assez satisfait du choix.
> Il y a peut-être mieux aujourd'hui

Il ne s'agit pas de récrire mais d'apprendre lorsqu'on débute ou que
l'on commence un peu à maitriser les choses.
Ensuite, avec l'expérience, il faut réutiliser ce qui existe pour ne pas
perdre son temps, je suis bien d'accord!



Hello,

Merci pour les explications ainsi que le lien.
Effectivement cette librairie fait exactement ce que je voulais et est
assez simple à utiliser
Parfait
Avatar
Jean-Marc Desperrier
Antonio a écrit :
Il ne s'agit pas de récrire mais d'apprendre lorsqu'on débute ou que
l'on commence un peu à maitriser les choses.
Ensuite, avec l'expérience, il faut réutiliser ce qui existe pour ne pas
perdre son temps, je suis bien d'accord!



Je ne suis pas vraiment d'accord. Les bonnes méthodes sont difficiles à
retrouver, ça ne vient que petit à petit. On apprend plus vite en lisant
et en s'inspirant des bonnes méthodes qu'en essayant tout le temps de
refaire soit-même.
Avatar
Gégé
On 6 jan, 09:55, Jean-Marc Desperrier wrote:
Antonio a écrit :

> Il ne s'agit pas de récrire mais d'apprendre lorsqu'on débute ou qu e
> l'on commence un peu à maitriser les choses.
> Ensuite, avec l'expérience, il faut réutiliser ce qui existe pour n e pas
> perdre son temps, je suis bien d'accord!

Je ne suis pas vraiment d'accord. Les bonnes méthodes sont difficiles à
retrouver, ça ne vient que petit à petit. On apprend plus vite en lis ant
et en s'inspirant des bonnes méthodes qu'en essayant tout le temps de
refaire soit-même.



Disons qu'il faut trouver un équilibre entre les 2 :)