美文网首页
多线程数据共享

多线程数据共享

作者: 是你亮哥哥呀 | 来源:发表于2019-08-29 11:10 被阅读0次

多线程数据共享时引发的问题:

  1. 有两个售票窗口,两个窗口同时查询了同一次列车的余票信息,然后同时锁定同一个座位并卖出,此时,同一个座位被出售了两次。
  2. 生产者/消费者

一、互斥量(mutex)

可以理解成一个锁,只有锁成功才会继续向下执行,否则阻塞线程。
使用原则:只保护需要保护的信息。

  1. lock(), unlock()必须成对出现
#include <iostream>
#include <thread>
#include <list>
#include <mutex>

using namespace std;

class A {
public:
    void inMsgRecvQueue()
    {
        for (int i = 0; i < 10000; ++i) {
            cout << "push one command : " << i << endl;
            my_mutex.lock();
            msgRecvQueue.push_back(i);
            my_mutex.unlock();
        }
    }

    bool outMsgProc(int &command) {
        my_mutex.lock();
        if (!msgRecvQueue.empty()) {
            //消息不为空
            command = msgRecvQueue.front();
            //cout << "received command is " << command << endl;
            msgRecvQueue.pop_front();
            my_mutex.unlock();  //解锁
            return true;
        }
        my_mutex.unlock(); //解锁
        return false;
    }
    void outMsgRecvQueue()
    {
        for (int i = 0; i < 10000; ++i) {
            int command = 0;
            while (!outMsgProc(command)) {
                //消息队列为空
                cout << "msgRecvQueue is empty" << endl;
            }
            cout << "received command is " << command << endl;
        }
    }
private:
    list<int> msgRecvQueue; //容器,收到的消息
    std::mutex my_mutex; //互斥量,lock()和unlock()必须成对使用
};

int main() {
    A myobj;
    std::thread myInMsgObj(&A::inMsgRecvQueue, &myobj);
    std::thread myOutMsgObj(&A::outMsgRecvQueue, &myobj);

    myInMsgObj.join();
    myOutMsgObj.join();

    return 0;
}
  1. std::lock_guard()类模板,取代lock()和unlock(),作用就是会主动析构,不再需要unlock()
    lock_guard构造函数里执行了lock(),lock_guard析构函数里执行了unlock(),所以当lock_guard对象生命周期结束,就会自行unlock()
#include <iostream>
#include <thread>
#include <list>
#include <mutex>

using namespace std;

class A {
public:
    void inMsgRecvQueue()
    {
        for (int i = 0; i < 10000; ++i) {
            cout << "push one command : " << i << endl;
            //my_mutex.lock();
            //msgRecvQueue.push_back(i);
            //my_mutex.unlock();
            { //第二种写法
                //{}显式声明sbguard的生命周期,出了{}sbguard会被系统自动回收,不再需要lock()和unlock()
                std::lock_guard<std::mutex> sbguard(my_mutex); 
                msgRecvQueue.push_back(i);
            }
            //do else...
        }
    }

    bool outMsgProc(int &command) {
        //my_mutex.lock();
        //if (!msgRecvQueue.empty()) {
        //  //消息不为空
        //  command = msgRecvQueue.front();
        //  //cout << "received command is " << command << endl;
        //  msgRecvQueue.pop_front();
        //  my_mutex.unlock();  //解锁
        //  return true;
        //}
        //my_mutex.unlock(); //解锁

        std::lock_guard<std::mutex> sbguard(my_mutex); //lock_guard构造函数里执行了lock()
                                                       //lock_guard析构函数里执行了unlock()
        if (!msgRecvQueue.empty()) {
            //消息不为空
            command = msgRecvQueue.front();
            //cout << "received command is " << command << endl;
            msgRecvQueue.pop_front();
            return true;
        }
        return false;
    }
    void outMsgRecvQueue()
    {
        for (int i = 0; i < 10000; ++i) {
            int command = 0;
            while (!outMsgProc(command)) {
                //消息队列为空
                cout << "msgRecvQueue is empty" << endl;
            }
            cout << "received command is " << command << endl;
        }
    }
private:
    list<int> msgRecvQueue; //容器,收到的消息
    std::mutex my_mutex; //互斥量,lock()和unlock()必须成对使用
};

int main() {
    A myobj;
    std::thread myInMsgObj(&A::inMsgRecvQueue, &myobj);
    std::thread myOutMsgObj(&A::outMsgRecvQueue, &myobj);

    myInMsgObj.join();
    myOutMsgObj.join();

    return 0;
}

相关文章

  • 同步函数需要注意的事项

    1,明确哪些代码是多线程运行代码。2,明确共享数据。3,明确多线程运行代码中哪些语句是操作共享数据的。 同步函数需...

  • Java 多线程(四):ThreadLocal 详解

    ThreadLocal 多线程在并发执行时,需要数据共享,因此才有了 volatile 变量解决多线程数据之间可见...

  • JAVA学习笔记之 多线程卖票

    多线程程序出现安全问题的原因:A:是多线程程序。B:有共享数据。C:针对共享数据有多条语句操作。 现在的程序存在着...

  • ThreadLocal解析

    原理 产生线程安全问题的根源在于多线程之间的数据共享。如果没有数据共享,就没有多线程并发安全问题。ThreadLo...

  • ThreadLocal解析

    原理 产生线程安全问题的根源在于多线程之间的数据共享。如果没有数据共享,就没有多线程并发安全问题。ThreadLo...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • iOS 多线程技术有些啥,如何解决多线程带来的隐患

    有多线程就有因为多线程造成的数据安全问题(如何确保同一块共享内存在多线程下不发生数据错乱和数据安全问题) 线程同步...

  • 多线程数据共享

    多线程数据共享时引发的问题: 有两个售票窗口,两个窗口同时查询了同一次列车的余票信息,然后同时锁定同一个座位并卖出...

  • UI数据源同步

    数据源同步问题多线程对共享数据的访问,需要考虑数据源的同步问题,如何解决tableView在多线程环境下的修改或者...

  • 2019-08-16 Synchronized的使用

    为什么要使用Synchronized关键字?为了解决线程高并发安全问题,共享数据,多线程共同操作共享数据,Sync...

网友评论

      本文标题:多线程数据共享

      本文链接:https://www.haomeiwen.com/subject/rcfbectx.html