2 votes

boost ne parvenant pas à obtenir le verrouillage

Je travaille sur une application musicale en temps réel. Je travaille avec la bibliothèque boost en tant que débutant. J'ai implémenté une relation Producteur/Consommateur avec une SyncronizedQueue protégée, en fait j'ai implémenté les sections 18.11 et 18.12 de https://www.quantnet.com/cplusplus-multithreading-boost/ . Lors de l'analyse de l'entrée midi, j'obtiens l'exception suivante :

terminate called after throwing an instance of 'boost::exception_detail::clone_impl
<boost::exception_detail::error_info_injector<boost::lock_error> >'
what():  boost::lock_error

Code pour analyser l'entrée dans le producteur :

RtMidiIn *midiin = new RtMidiIn();
std::vector<unsigned char> message;
int nBytes, i;
double stamp;
m_queue=queue;        

// Check available ports.
unsigned int nPorts = midiin->getPortCount();
if ( nPorts == 0 ) {
    std::cout << "No ports available!\n";
    goto cleanup;
}

midiin->openPort( 1 );

// Don't ignore sysex, timing, or active sensing messages.
midiin->ignoreTypes( false, false, false );

// Install an interrupt handler function.
done = false;
(void) signal(SIGINT, finish);

// Periodically check input queue.
std::cout << "Reading MIDI from port ... quit with Ctrl-C.\n";
while ( !done ) {
  stamp = midiin->getMessage( &message );
  nBytes = message.size();
  if(nBytes>0){
    if((message.size()!=1)&&((int)message.at(0)!=137)){
            for ( i=0; i<nBytes; i++ )
            std::cout << "Byte " << i << " = " << (int)message[i] << ", ";
            if ( nBytes > 0 )
            std::cout << "stamp = " << stamp << std::endl;
            m_queue->Enqueue("asd");
    }
}
}

il se casse à la première rencontre :

m_queue->Enqueue("asd");

En essayant de l'exécuter :

boost::unique_lock<boost::mutex> lock(m_mutex);

Toute aide est appréciée !

EDIT1 :

Il s'agit de l'objet SynchronizedQueue. L'exception est levée lors de l'appel de Enqueue().

template <typename T>
class SynchronizedQueue
{
private:
    std::queue<T> m_queue;                      // Use STL queue to store data
    mutable boost::mutex m_mutex;                       // The mutex to synchronise on
    boost::condition_variable m_cond;       // The condition to wait for

public:

    // Add data to the queue and notify others
    void Enqueue(const T& data)
    {
        // Acquire lock on the queue
            boost::unique_lock<boost::mutex> lock(m_mutex);
        // Add the data to the queue
        m_queue.push(data);
            // Notify others that data is ready
        m_cond.notify_one();
        } // Lock is automatically released here

    // Get data from the queue. Wait for data if not available
    T Dequeue()
    {

        // Acquire lock on the queue
        boost::unique_lock<boost::mutex> lock(m_mutex);
        //lock();
        // When there is no data, wait till someone fills it.
        // Lock is automatically released in the wait and obtained 
        // again after the wait
        while (m_queue.size()==0) m_cond.wait(lock);

        // Retrieve the data from the queue
        T result=m_queue.front(); m_queue.pop();
        return result;
    } // Lock is automatically released here
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X