2013-04-29 92 views
1

我的程序有三個線程,我正在嘗試瞭解同步和線程安全。下面我概述了不同線程的作用,但我想了解如何使用事件來觸發不同線程中的每個進程,而不是無限地讀取(這給我的併發性問題)。多線程和使用事件

谷歌搜索引發了很多選擇,但我不確定什麼是最好的實施在這種情況下 - 你能指出一個標準的方法/事件,我可以學習最好地實現這個方向?

我在VS 2012上這樣做,理想情況下我不會使用外部庫例如促進。

線程1:接收消息並將其推入全局隊列queue<my_class> msg_in。線程2:關於無限循環(即while(1));線程2:關於無限循環(即while(1));線程2:關於無限循環(即while(1));等到if (!msg_in.empty()),做一些處理,並將其推入全球map<map<queue<my_class>>> msg_out

while (1) 
{ 
    if (!msg_in.empty()) 
    { 
     //processes 
     msg_map[i][j].push(); //i and j are int (irrelevant here) 
    } 

} 

主題3:

while (1) 
{ 
    if (msg_map.find(i) != msg_map.end()) 
    { 
     if (!msg_map[i].find(j)->second.empty()) 
     { 
      //processes 
     } 
    } 
} 

回答

0

你的問題是生產者消費者問題。你可以爲你的事件使用條件變量。這裏有一個例子:http://en.cppreference.com/w/cpp/thread/condition_variable

我已經適應了你的例子,如果你需要它。

#include "MainThread.h" 


#include <iostream> 
#include <string> 
#include <thread> 
#include <mutex> 
#include <atomic> 
#include <condition_variable> 

std::mutex m; 
std::condition_variable cv; 
bool ready = false; 
bool processed = false; 

void worker_thread(unsigned int threadNum) 
{ 
    // Wait until main() sends data 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return ready;}); 
    } 

    std::cout << "Worker thread "<<threadNum <<" is processing data"<<std::endl; 

    // Send data back to main() 
    { 
     std::lock_guard<std::mutex> lk(m); 
     processed = true; 
     std::cout << "Worker thread "<< threadNum <<" signals data processing completed\n"; 
    } 
    cv.notify_one(); 
} 


int initializeData() 
{ 
    // send data to the worker thread 
    { 
     std::lock_guard<std::mutex> lk(m); 
     ready = true; 
     std::cout << "Data initialized"<<std::endl; 
    } 
    cv.notify_one(); 
    return 0; 
} 

int consumerThread(unsigned int nbThreads) 
{ 
    std::atomic<unsigned int> nbConsumedthreads=0; 
    while (nbConsumedthreads<nbThreads) 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return processed;}); 
     std::cout<<"Data processed counter="<<nbConsumedthreads << " "<< std::endl; 
     ++nbConsumedthreads; 
     cv.notify_one(); 
    } 

    return 0; 
} 

int main() 
{ 
    const unsigned int nbThreads=3; 
    std::thread worker1(worker_thread,1); 
    std::thread worker2(worker_thread,2); 
    std::thread worker3(worker_thread,3); 

    std::thread init(initializeData); 

    std::thread consume(consumerThread, nbThreads); 



    worker1.join(); 
    worker2.join(); 
    worker3.join(); 

    init.join(); 

    consume.join(); 

    return 0; 
} 

希望幫助,告訴我,如果你需要更多的信息。