2013-04-15 2 views
0

Dans l'exemple suivant j'utilise boost ASIO, ici un thread est prêt et attend toujours un travail à faire.Il va toujours faire des jobs linéairement (comme si les jobs sont stockés dans un file d'attente que je comprends) L'extrait de code suivant explique mon point.Utilise un IO_Service déjà créé thread plus efficace

void WorkerThread(boost::shared_ptr<boost::asio::io_service> io_service) 
{ 
    io_service->run(); 
} 

void PrintNum(int x) 
{ 
    //Do somejon 
} 

boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service); 
boost::shared_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(*io_service)); 
boost::asio::io_service::strand strand(*io_service); 
worker_threads.create_thread(boost::bind(&WorkerThread, io_service)); 
//Give the thread (which is already active) some work to do 
for(int i=0;i<2;i++) 
{ 
    strand.post(boost::bind(&PrintNum, i)); 
} 

Question 1

Maintenant, ma question est de savoir si la méthode ci-dessus est plus rapide et plus efficace que le lancement de thread indépendants (par exemple en utilisant boost::thread) Je sais que dans le cas de threads indépendants tels que par boost::thread le lancement des threads peut ne pas être linéaire (le thread 2 pourrait s'exécuter avant le thread 1) ma question est au cas où il n'y aurait qu'un thread impliqué quel mécanisme aurait été plus rapide? Y at-il en tête becaus eof boost :: bind

Question 2 Dans l'exemple ci-dessus 2 fils sont lancés qui attendent pour le travail (thread1 et thread2). Maintenant, je voulais savoir ce qui se passe exactement quand le travail est 2 consécutivement donné en tant que telle

for(int i=0;i<2;i++) 
{ 
    strand.post(boost::bind(&PrintNum, i)); 
} 

Chaque thread obtient un emploi fil cependant 2 wont complet avant fil 1. Mes questions sont ce qui se passe avec le fil 2 pendant que le fil de discussion est lancé même s'il entre dans la méthode PrintNum tandis que le fil 1 est lancé. Quel est le point d'avoir plus d'un fil alors dans un tel cas quand il s'agit de la performance?

Répondre

1

Les threads et les E/S asynchrones ne sont pas des optimisations de performance. Ce sont des techniques utilisées pour cacher la latence.

Question 1: boost :: bind est relativement bon marché. Cela crée simplement un objet fonction. Le lancement de threads est extrêmement coûteux. La synchronisation entre les threads est assez coûteuse (pas aussi coûteuse que la création d'un nouveau thread, mais plus coûteuse que la création d'un objet fonction). Des opérations comme strand.post() font vraisemblablement beaucoup de synchronisation (communiquer des valeurs entre threads, s'assurer que les choses se passent dans des ordres particuliers).

Question 2: Thread 2 (en supposant que la bibliothèque le crée plutôt que de l'optimiser en quelque sorte) bloquera l'attente du thread 1 pour terminer son traitement avant que thread 2 appelle même PrintNum.

Il ne sert à rien d'avoir deux threads s'ils passent la majeure partie de leur temps à se bloquer les uns les autres.

Les séquences d'opérations dépendantes doivent pour la plupart être mappées sur le même thread. (Comme PrintNum (0); PrintNum (1) dans votre cas: vous voulez qu'ils fonctionnent dans l'ordre, alors mettez-les dans le même fil.)

Commencez un nouveau fil si vous avez quelque chose à faire c'est presque complètement indépendant de ce que vous faites actuellement. Un exemple serait: vous écrivez un serveur qui établit des connexions avec plusieurs utilisateurs ou périphériques. Comme chaque utilisateur ou périphérique fonctionne à sa propre vitesse, demande un service ou répond aux questions du serveur, vous pouvez créer un thread pour interagir avec chaque utilisateur ou périphérique. De cette façon, si un utilisateur s'en va pendant quelques minutes, tous les autres utilisateurs peuvent continuer à interagir avec leur thread sans bloquer l'attente de l'utilisateur absent. Mais le service que vous effectuez pour un utilisateur individuel va dans un certain ordre ("l'utilisateur demande A, donc je recherche A, je fais un traitement dessus puis je le renvoie à l'utilisateur") donc ne divisez pas le service effectuer pour un utilisateur dans différents threads.

Questions connexes