问题

  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4. using namespace std;
  5. void function_1() {
  6. for (int i = 0; i > -100; i--)
  7. cout << "From t1:" << i << endl;
  8. }
  9. int main() {
  10. thread t1(function_1);
  11. for (int i = 0; i > -100; i--)
  12. cout << "From main:" << i << endl;
  13. t1.join();
  14. return 0;
  15. }
  • main线程和function_1线程争抢cout资源,导致输出错乱
  • 本来cout在打印main的内容,被打断,打印function_1内容

加互斥锁

  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4. #include <mutex>
  5. std::mutex mu;
  6. void share_print(std::string msg,int id) {
  7. mu.lock();
  8. std::cout << msg << id << std::endl;
  9. mu.unlock();
  10. }
  11. void function_1() {
  12. for (int i = 0; i > -100; i--)
  13. share_print("From t1:", i);
  14. }
  15. int main() {
  16. std::thread t1(function_1);
  17. for (int i = 0; i > -100; i--)
  18. share_print("From main:", i);
  19. t1.join();
  20. return 0;
  21. }
  • 互斥量类 mutex
  • lock方法,当有一个线程执行到cout前,对这一段上锁
  • 另一个线程想要执行cout,如果有锁,无法执行,被挂起
  • 执行完cout才可解锁,让下一个线程执行
  • 存在问题
    • 如果lock和unlock之间出现异常,会导致始终锁着,线程始终无法进行

防异常互斥

  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4. #include <mutex>
  5. std::mutex mu;
  6. void share_print(std::string msg,int id) {
  7. std::lock_guard<std::mutex> guard(mu);
  8. std::cout << msg << id << std::endl;
  9. }
  10. void function_1() {
  11. for (int i = 0; i > -100; i--)
  12. share_print("From t1:", i);
  13. }
  14. int main() {
  15. std::thread t1(function_1);
  16. for (int i = 0; i > -100; i--)
  17. share_print("From main:", i);
  18. t1.join();
  19. return 0;
  20. }
  • 使用lock_guard可以自动完成上锁和开锁,如果保护内容发生异常,会自动开锁
  • 存在问题
    • cout是全局变量,除了这两个线程会用,其它地方也会抢占
    • cout没有完全在互斥对象mu的保护下
    • 互斥资源必须和互斥对象进行绑定

互斥锁私有资源

  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. private:
  12. std::mutex m_mutex;
  13. std::ofstream f;//f是被mutex所保护的资源
  14. };
  15. LofFile::LofFile(){
  16. f.open("log.txt");
  17. }
  18. LofFile::~LofFile(){
  19. }
  20. void LofFile::share_print(std::string id, int value){
  21. std::lock_guard<std::mutex> locker(m_mutex);
  22. f << "from" << id << ":" << value << std::endl;
  23. }
  24. void function_1(LofFile& log) {
  25. for (int i = 0; i > -100; i--)
  26. log.share_print("From function_1:", i);
  27. }
  28. int main() {
  29. LofFile log;
  30. std::thread t1(function_1,std::ref(log));
  31. for (int i = 0; i > -100; i--)
  32. log.share_print("From main:", i);
  33. t1.join();
  34. return 0;
  35. }
  • 用文件操作代替cout
  • 文件操作和互斥锁绑定
  • 两个线程将抢夺的是LofFile类资源