[résolu] Implémentation des lecteurs/écrivains

Implémentation des lecteurs/écrivains [résolu] - C++ - Programmation

Marsh Posté le 12-08-2010 à 11:41:54    

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 :
  1. #include <list>
  2. #include <boost/thread.hpp>
  3. #include <boost/thread/mutex.hpp>
  4. #include <boost/thread/condition.hpp>
  5. #include <cstdio>
  6. #include <cstdlib>
  7. #include <ctime>
  8. #include <windows.h>
  9. bool stop;
  10. std::list< int > queue;
  11. int maxQueue = 10;
  12. boost::condition condNotFull, condNotEmpty;
  13. boost::mutex mutex;
  14. void writer()
  15. {
  16.     std::cout << "++writer starts" << std::endl;
  17.     while( !stop )
  18.     {
  19.         boost::mutex::scoped_lock lock( mutex );
  20.         // file pleine
  21.         while( queue.size() == maxQueue-1 )
  22.         {
  23.             std::cout << "++writer: waiting" << std::endl;
  24.             condNotFull.wait( lock );
  25.         }
  26.         // calcul à la con qui dure à peu près 1 seconde sur ma machine
  27.         int val;
  28.         for( unsigned int idx = 0; idx < 10000000; idx++ )
  29.             val = rand() % 100;
  30.         queue.push_back( val );
  31.         std::cout << "++writer: [" << queue.size() << "] = " << val << std::endl;
  32.         // notif file non vide
  33.         condNotEmpty.notify_one();
  34.     }
  35. }
  36. void reader()
  37. {
  38.     std::cout << "--reader starts" << std::endl;
  39.     while( !stop )
  40.     {
  41.         {
  42.             boost::mutex::scoped_lock lock( mutex );
  43.             // file vide
  44.             while( queue.size() == 0 )
  45.             {
  46.                 std::cout << "--reader: waiting" << std::endl;
  47.                 condNotEmpty.wait( lock );
  48.             }
  49.             int val = queue.front();
  50.             queue.pop_front();
  51.             std::cout << "--reader: [" << queue.size() << "] = " << val << std::endl;
  52.             // notif file non pleine
  53.             condNotFull.notify_one();
  54.         }
  55.         Sleep( 100 );
  56.     }
  57. }
  58. int main(int argc, char* argv[])
  59. {
  60.     stop = false;
  61.     // on lance le writer
  62.     boost::thread threadWriter = boost::thread( &writer );
  63.     srand ( time(0) );
  64.     // on laisse le writer prendre de l'avance
  65.     Sleep( 5000 );
  66.     // on lance le reader
  67.     boost::thread threadReader = boost::thread( &reader );
  68.     Sleep( 50000 );
  69.     stop = true;
  70.     return 0;
  71. }


 
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.
Reply

Marsh Posté le 12-08-2010 à 11:41:54   

Reply

Marsh Posté le 12-08-2010 à 11:47:51    

Si j'ai bien compris le code ,est ce que tu ne devrai pas prendre le lock juste au moment de l'ecriture pour l'ecrivain ? Là , j'ai l'impression qu'il bloque la file meme lorsqu'il fait son calcul

 

un truc du genre : ( surement faux, je ne connais aps le C++ :d )

Code :
  1. void writer()
  2. {
  3.    std::cout << "++writer starts" << std::endl;
  4.    while( !stop )
  5.    {
  6.       // calcul à la con qui dure à peu près 1 seconde sur ma machine
  7.        int val;
  8.        for( unsigned int idx = 0; idx < 10000000; idx++ )
  9.            val = rand() % 100;
  10.        boost::mutex::scoped_lock lock( mutex );
  11.        // file pleine
  12.        while( queue.size() == maxQueue-1 )
  13.        {
  14.            std::cout << "++writer: waiting" << std::endl;
  15.            condNotFull.wait( lock );
  16.        }
  17.      
  18.        queue.push_back( val );
  19.        std::cout << "++writer: [" << queue.size() << "] = " << val << std::endl;
  20.        // notif file non vide
  21.        condNotEmpty.notify_one();
  22.    }
  23. }


Message édité par flo850 le 12-08-2010 à 11:48:10
Reply

Marsh Posté le 12-08-2010 à 12:04:02    

Oui tu as raison, je viens de voir ça ! Merci !


---------------
Be the one with the flames.
Reply

Marsh Posté le 12-08-2010 à 13:12:11    

:sol:
a noter que le lecteur a le même problème, il bloque la file tant que la file est vide  [:stefro] et que l'ecrivain bloque la file tant que la file est pleine  [:akilae]


Message édité par flo850 le 12-08-2010 à 13:13:29
Reply

Marsh Posté le 12-08-2010 à 14:39:59    

Oui oui j'avais bien noté !


---------------
Be the one with the flames.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed