C++ 线程互斥

竞态条件:多线程执行结果应该是一致的,不应该因CPU 对线程的调用顺序不一样,而导致结果不一样,这也是多线程对全局量的共享,导致数据不一致,因此要保证线程的安全

 

例子如下:

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<unistd.h>
#include<list>
#include<thread>
using namespace std;
int count = 100;

// 模拟卖票的线程函数
void SellTicket(int  i) {

  while(count>0) {
  cout<<"窗口"<<i<<"卖出第"<<count<<"张票"<<endl;
  count--;
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  }

}

int main()
{

  list<std::thread> tlist;
  for(int i = 0 ;i < 3; i++) {
    tlist.push_back(std::thread(SellTicket,i));
  }

  for(std::thread &t : tlist) {
    t.join();
  }
    cout<<"所有窗口完成卖票"<<endl;
    return 0;
}

当把数据从内存读到寄存器中,通过运算单元计算完,并没有写回内存,这个线程被挂起,那么就会导致内存中的数据没有被修改,因此需要使用互斥锁。

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<unistd.h>
#include<list>
#include<thread>
#include<mutex>
using namespace std;
int count = 100;
std::mutex mtu;
// 模拟卖票的线程函数
void SellTicket(int  i) {

  while(count>0) {
    mtu.lock();
    //  这里还是存在问题,当count 为1 的时候,此时有两个线程都进来,但是一个线程没有真正的进行count-- , 那么另一个线程阻塞在lock() ,当
    //  第一个线程释放锁之后,那么第二个线程还是会进行count-- ,不正确。
    //  因此需要锁加双层判断
    
    if(count >0 ) {
    cout<<""<<i<<"窗口:"<<count<<endl;
    count--;
    }
  mtu.unlock();
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }

}

int main()
{

  list<std::thread> tlist;
  for(int i = 0 ;i < 3; i++) {
    tlist.push_back(std::thread(SellTicket,i));
  }

  for(std::thread &t : tlist) {
    t.join();
  }
    cout<<"所有窗口完成卖票"<<endl;
    return 0;
}

这里就使用了 std::mutex  

 

这里有点像智能指针一样管理互斥锁  lock_guard  (是个类 接收一个互斥锁)  //  类似于智能指针的scoped_ptr 

例如 :std::mutex  mut;

          lock_guard<std::mutex> lock(mut);   //  保证unlock() 一定被调用到,不会造成死锁

当出作用域就析构,也就是释放锁

unique_lock  允许右值引用的拷贝构造和赋值

unique_lock<std::mutex> _lock(mut):

_lock.lock();

_lock.unlock();

 

posted @ 2020-09-02 17:09  睡觉lc  阅读(267)  评论(0编辑  收藏  举报