死锁产生

  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4. #include <mutex>
  5. #include <fstream>
  6. class LofFile{
  7. public:
  8. LofFile();
  9. ~LofFile();
  10. void share_print(std::string id, int value);
  11. void share_print2(std::string id, int value);
  12. private:
  13. std::mutex m_mutex;
  14. std::mutex m_mutex2;
  15. std::ofstream f;//f是被mutex所保护的资源
  16. };
  17. LofFile::LofFile(){
  18. f.open("log.txt");
  19. }
  20. LofFile::~LofFile(){
  21. }
  22. void LofFile::share_print(std::string id, int value){
  23. std::lock_guard<std::mutex> locker(m_mutex);
  24. std::lock_guard<std::mutex> locker2(m_mutex2);
  25. std::cout << "from" << id << ":" << value << std::endl;
  26. }
  27. void LofFile::share_print2(std::string id, int value) {
  28. std::lock_guard<std::mutex> locker2(m_mutex2);
  29. std::lock_guard<std::mutex> locker(m_mutex);
  30. std::cout << "from" << id << ":" << value << std::endl;
  31. }
  32. void function_1(LofFile& log) {
  33. for (int i = 0; i > -100; i--)
  34. log.share_print("From function_1", i);
  35. }
  36. int main() {
  37. LofFile log;
  38. std::thread t1(function_1,std::ref(log));
  39. for (int i = 0; i > -100; i--)
  40. log.share_print2("From main", i);
  41. t1.join();
  42. return 0;
  43. }
  • 当function_1线程锁住m_mutex
  • main线程锁住m_mutex2
  • function_1等待m_mutex2解锁
  • main等待m_mutex解锁
  • 导致死锁

死锁避免

  • 评估是否需要两个以上的锁
  • 避免调用mutex的同时调用其他的不熟悉的函数,有可能这个函数包含了其它的另外的锁
  • 使用C++标准库提供的lock函数,可以确保多个mutex的顺序是相同的(部分极端场合,lock函数不能使用)

方法1:确保每一个locker顺序相同

方法2:C++提供机制

  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4. #include <mutex>
  5. #include <fstream>
  6. class LofFile{
  7. public:
  8. LofFile();
  9. ~LofFile();
  10. void share_print(std::string id, int value);
  11. void share_print2(std::string id, int value);
  12. private:
  13. std::mutex m_mutex;
  14. std::mutex m_mutex2;
  15. std::ofstream f;//f是被mutex所保护的资源
  16. };
  17. LofFile::LofFile(){
  18. f.open("log.txt");
  19. }
  20. LofFile::~LofFile(){
  21. }
  22. void LofFile::share_print(std::string id, int value){
  23. //按顺序上锁
  24. std::lock(m_mutex, m_mutex2);
  25. //locker获取mutex的所有权,析构时解锁mutex
  26. std::lock_guard<std::mutex> locker(m_mutex,std::adopt_lock);
  27. std::lock_guard<std::mutex> locker2(m_mutex2, std::adopt_lock);
  28. std::cout << "from" << id << ":" << value << std::endl;
  29. }
  30. void LofFile::share_print2(std::string id, int value) {
  31. //按顺序上锁
  32. std::lock(m_mutex, m_mutex2);
  33. //locker获取mutex的所有权,析构时解锁mutex
  34. std::lock_guard<std::mutex> locker2(m_mutex2, std::adopt_lock);
  35. std::lock_guard<std::mutex> locker(m_mutex, std::adopt_lock);
  36. std::cout << "from" << id << ":" << value << std::endl;
  37. }
  38. void function_1(LofFile& log) {
  39. for (int i = 0; i > -100; i--)
  40. log.share_print("From function_1", i);
  41. }
  42. int main() {
  43. LofFile log;
  44. std::thread t1(function_1,std::ref(log));
  45. for (int i = 0; i > -100; i--)
  46. log.share_print2("From main", i);
  47. t1.join();
  48. return 0;
  49. }