2012-06-05 44 views
1

我正在研究實時音樂應用程序。使用boost庫作爲新手。 我使用受保護的SyncronizedQueue實現了Producer/Consumer關係,實際上我實現了https://www.quantnet.com/cplusplus-multithreading-boost/的18.11和18.12部分。 當解析MIDI輸入我得到以下異常:提升失敗獲取鎖定

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 

規範生產者解析輸入:

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"); 
    } 
} 
} 

它打破的第一次遇到:

m_queue->Enqueue("asd"); 

當試圖執行:

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

任何幫助表示讚賞!編號1:

這是SynchronizedQueue對象。調用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 
}; 
+1

難道線程試圖在此互斥鎖可以以某種方式導致死鎖?如果你看'boost :: lock_error',拋出這個異常的原因是:「lock_error異常包括一個鎖定操作,它可以被確定爲導致死鎖」 –

+0

很難調試這個,不知道不同的線程會怎麼樣,和哪個線程做什麼。 –

+0

嘿託尼,謝謝你的提示。只有兩個線程,生產者和消費者。生產者是上面顯示的那個。當我註釋掉m_queue-> Enqueue時,它會正常工作,通過添加實現的鎖定機制來更新。 –

回答

3

大多數時候,當我偶然發現這樣一個問題,就是被鎖定的互斥鎖已經被銷燬或者沒有被構造。當解析器線程開始解析時,你確定,你傳遞給解析器的隊列是否已經構造?或者它可能是,包含隊列作爲本地變量的循環的退出停止?也許你可以做一個快速的測試,並在隊列中添加一個代碼並在那裏設置一個斷點。

問候 託斯滕