Hello,
J'ai un cas de lecteur/écrivain, et j'ai du mal à l'implémenter comme je le souhaite.
Mon écrivain produit des données moins vite que ce que lit mon lecteur, j'ai donc mis en place une file qui stocke les résultats de l'écrivain, et je fais démarrer l'écrivain plus tôt pour qu'il prenne de l'avance sur le lecteur.
Mon problème est que le lecteur lit au rythme de l'écrivain, et non pas à son propre rythme.
Voici le code exemple :
Code :
- #include <list>
- #include <boost/thread.hpp>
- #include <boost/thread/mutex.hpp>
- #include <boost/thread/condition.hpp>
- #include <cstdio>
- #include <cstdlib>
- #include <ctime>
- #include <windows.h>
- bool stop;
- std::list< int > queue;
- int maxQueue = 10;
- boost::condition condNotFull, condNotEmpty;
- boost::mutex mutex;
- void writer()
- {
- std::cout << "++writer starts" << std::endl;
- while( !stop )
- {
- boost::mutex::scoped_lock lock( mutex );
- // file pleine
- while( queue.size() == maxQueue-1 )
- {
- std::cout << "++writer: waiting" << std::endl;
- condNotFull.wait( lock );
- }
- // calcul à la con qui dure à peu près 1 seconde sur ma machine
- int val;
- for( unsigned int idx = 0; idx < 10000000; idx++ )
- val = rand() % 100;
- queue.push_back( val );
- std::cout << "++writer: [" << queue.size() << "] = " << val << std::endl;
- // notif file non vide
- condNotEmpty.notify_one();
- }
- }
- void reader()
- {
- std::cout << "--reader starts" << std::endl;
- while( !stop )
- {
- {
- boost::mutex::scoped_lock lock( mutex );
- // file vide
- while( queue.size() == 0 )
- {
- std::cout << "--reader: waiting" << std::endl;
- condNotEmpty.wait( lock );
- }
- int val = queue.front();
- queue.pop_front();
- std::cout << "--reader: [" << queue.size() << "] = " << val << std::endl;
- // notif file non pleine
- condNotFull.notify_one();
- }
- Sleep( 100 );
- }
- }
- int main(int argc, char* argv[])
- {
- stop = false;
- // on lance le writer
- boost::thread threadWriter = boost::thread( &writer );
- srand ( time(0) );
- // on laisse le writer prendre de l'avance
- Sleep( 5000 );
- // on lance le reader
- boost::thread threadReader = boost::thread( &reader );
- Sleep( 50000 );
- stop = true;
- return 0;
- }
|
En sortie j'ai quelque chose comme ça :
Citation :
++writer starts
++writer: [1] = 79
++writer: [2] = 28
++writer: [3] = 74
++writer: [4] = 5
++writer: [5] = 81
++writer: [6] = 26
++writer: [7] = 32
--reader starts
++writer: [8] = 55
--reader: [7] = 79
++writer: [8] = 19
--reader: [7] = 28
++writer: [8] = 52
--reader: [7] = 74
++writer: [8] = 74
--reader: [7] = 5
++writer: [8] = 13
--reader: [7] = 81
++writer: [8] = 93
--reader: [7] = 26
++writer: [8] = 70
--reader: [7] = 32
++writer: [8] = 36
--reader: [7] = 55
++writer: [8] = 83
--reader: [7] = 19
++writer: [8] = 67
--reader: [7] = 52
++writer: [8] = 48
--reader: [7] = 74
++writer: [8] = 82
--reader: [7] = 13
++writer: [8] = 61
--reader: [7] = 93
...
|
Comme on le voit, la file est toujours pratiquement pleine, alors que je voudrais que celle-ci se vide.
En gros je veux que le lecteur ait ce qu'il désire dès qu'il le demande.
Savez-vous comment faire ce genre de chose ?
Message édité par Riot le 12-08-2010 à 12:04:21
---------------
Be the one with the flames.