zoukankan      html  css  js  c++  java
  • 多线程间的互斥-锁(下)

    问题:程序有多少临界资源?需要多少线程锁?

    临界资源是没有任何的限制

    一般性原则:每一个临界资源都需要一个线程锁进行保护(一 一对应)

    定义了两把线程锁,显然是为了保护两个临界资源而定义的。在线程A中需要两个临界资源才能保证工作,这两个临界资源对应的线程锁就是m1,m2。在线程B中也需要两个临界资源才能保证工作。单看线程A和线程B都是正确的,那么它们两个加在一起就是多线程程序吗?这是一个非常有趣的问题,有趣的地方在于它们获取线程锁的顺序是不一样的。接下来就进行研究 

    有趣的示例:

    复制代码
    #include <QCoreApplication>
    #include <QThread>
    #include <QDebug>
    #include <QMutex>
    
    QMutex q_mutex_1;
    QMutex q_mutex_2;
    
    class ThreadA : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                q_mutex_1.lock();
    
                qDebug() << objectName() << "get m1";
    
                q_mutex_2.lock();
    
                qDebug() << objectName() << "get m2";
    
                qDebug() << objectName() << "do work....";
    
                q_mutex_2.unlock();
                q_mutex_1.unlock();
            }
    
        }
    };
    
    class ThreadB : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                q_mutex_2.lock();
    
                qDebug() << objectName() << "get m2";
    
                q_mutex_1.lock();
    
                qDebug() << objectName() << "get m1";
    
                qDebug() << objectName() << "do work....";
    
                q_mutex_1.unlock();
                q_mutex_2.unlock();
            }
        }
    };
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        ThreadA ta;
        ThreadB tb;
    
        ta.setObjectName("ta");
        tb.setObjectName("tb");
    
        ta.start();
        tb.start();
        return a.exec();
    }
    复制代码

    打印结果1:(注意这个地方的打印结果是不确定的)

     上面已经分析过,线程A和线程B要想正确的执行,需要得到两把锁,m1和m2.。从打印结果看,线程A只得到了,锁m1,线程B得到了锁m2。当线程A在获得了锁m1后,再尝试获取第二把锁m2,但是此时锁m2被线程B得到了,线程A等待线程B释放m2,才能继续往下执行。然而,线程B等待线程A释放m1,才能继续向下运行。这两个线程都在互相等待,谁也不释放锁,这样就造成了无限的等待,造成了死锁。

    线程A和线程B获取线程锁的顺序是不一样的。 

    线程的死锁概念

    -线程间相互等待临界资源而造成彼此无法继续执行

    发生死锁的条件:

    -系统中存在多个临界资源且临界资源不可抢占

    -线程需要多个临界资源才能继续执行

     

     m1保护r1,m2保护r2,依次类推。

    复制代码
    QMutex q_mutex_1;
    QMutex q_mutex_2;
    
    class ThreadA : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                q_mutex_1.lock();
    
                qDebug() << objectName() << "get m1";
    
                q_mutex_2.lock();
    
                qDebug() << objectName() << "get m2";
    
                qDebug() << objectName() << "do work....";
    
                q_mutex_2.unlock();
                q_mutex_1.unlock();
    
                sleep(1);
            }
    
        }
    };
    
    class ThreadB : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                q_mutex_1.lock();
    
                qDebug() << objectName() << "get m1";
    
                q_mutex_2.lock();
    
                qDebug() << objectName() << "get m2";
    
                qDebug() << objectName() << "do work....";
    
                q_mutex_2.unlock();
                q_mutex_1.unlock();
    
                sleep(1);
            }
        }
    };
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        ThreadA ta;
        ThreadB tb;
    
        ta.setObjectName("ta");
        tb.setObjectName("tb");
    
        ta.start();
        tb.start();
        return a.exec();
    }
    复制代码
  • 相关阅读:
    51Nod 1016 水仙花数 V2(组合数学,枚举打表法)
    April Fools Contest 2017 题解&源码(A,数学 B,数学 C,数学 D,字符串 E,数字逻辑 F,排序,卡时间,G,数学)
    统计0到n之间1的个数[数学,动态规划dp](经典,详解)
    hihoCoder #1082 : 然而沼跃鱼早就看穿了一切(字符串处理)
    洛谷 P1876 开灯(思维,枚举,规律题)
    Codeforces 789A Anastasia and pebbles(数学,思维题)
    51Nod 1182 完美字符串(字符串处理 贪心 Facebook Hacker Cup选拔)
    机器学习(Machine Learning)&深度学习(Deep Learning)资料
    看一下你在中国属于哪个阶层?
    python读取mnist
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14320685.html
Copyright © 2011-2022 走看看