C++11 多线程 发表于 2019-06-08 | 分类于 mult-thread 多线程死锁1、死锁实例: 连环锁 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465#include <iostream> #include <queue>#include <thread> #include <mutex> #include <condition_variable> std::mutex g_mutex;std::condition_variable g_produce, g_consume; std::queue<int> g_queue; static const int maxSize = 100;static const int consumeSize = 5;static const int productSize = 10;void consumer() { while(g_queue.size() <= maxSize ) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::unique_lock<std::mutex> lck(g_mutex); g_consume.wait(lck); std::cout << "@@@-> consumer " << ": "; std::cout << std::this_thread::get_id() << " : "; if(g_queue.size() > 0) g_queue.pop(); std::cout << g_queue.size() << '\n'; // nodity(wake up) producer g_produce.notify_all(); }}void producer(){ while(g_queue.size() <= maxSize) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::unique_lock<std::mutex> lck(g_mutex); g_produce.wait_for(lck,std::chrono::seconds(1)); std::cout << "###-> producer " << ": "; std::cout << std::this_thread::get_id() << " : "; g_queue.push(99); std::cout << g_queue.size() << '\n'; // notify(wake up) consumer g_consume.notify_all(); } }int main(int argc, char const *argv[]){ std::vector<std::thread> vcthread; for (int i = 0; i < 2; ++i) { vcthread.emplace_back(producer); vcthread.emplace_back(consumer); } for( auto & th : vcthread) th.join(); return 0;} 修改如下, 调整锁的作用域 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#include <iostream> #include <queue>#include <thread> #include <mutex> #include <condition_variable> std::mutex g_mutex;std::condition_variable g_produce, g_consume; std::queue<int> g_queue; static const int maxSize = 100;static const int consumeSize = 5;static const int productSize = 10;void consumer() { std::unique_lock<std::mutex> lck(g_mutex); while(g_queue.size() <= maxSize ) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout << "@@@<<<" << "\n"; g_consume.wait(lck); std::cout << "@@@-> consumer " << ": "; std::cout << std::this_thread::get_id() << " : "; if(g_queue.size() > 0) g_queue.pop(); std::cout << g_queue.size() << '\n'; // nodity(wake up) producer g_produce.notify_all(); }}void producer(){ std::unique_lock<std::mutex> lck(g_mutex); while(g_queue.size() <= maxSize) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); if(g_queue.size() == 0) { std::cout << "####<<<" << "\n"; g_produce.wait_for(lck,std::chrono::seconds(1)); } else { std::cout << "####>>>" << "\n"; g_produce.wait(lck); } std::cout << "###-> producer " << ": "; std::cout << std::this_thread::get_id() << " : "; g_queue.push(99); std::cout << g_queue.size() << '\n'; // notify(wake up) consumer g_consume.notify_all(); } }int main(int argc, char const *argv[]){ std::vector<std::thread> vcthread; for (int i = 0; i < 2; ++i) { vcthread.emplace_back(producer); vcthread.emplace_back(consumer); } for( auto & th : vcthread) th.join(); return 0;}