Boost / Threads / Mutex
Le
Gégé

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 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;
}
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 :
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+
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!
Hello,
Merci pour les explications ainsi que le lien.
Effectivement cette librairie fait exactement ce que je voulais et est
assez simple à utiliser
Parfait
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.
Disons qu'il faut trouver un équilibre entre les 2 :)