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();
    }
    复制代码
  • 相关阅读:
    hiveserver2 with kerberos authentication
    python Basic usage
    python Quicksort demo
    Python HeapSort
    mrunit for wordcount demo
    CCDH证书
    Hadoop question list
    Hadoop Yarn core concepts
    Hadoop Resource
    Hadoop could not find or load main class
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14320685.html
Copyright © 2011-2022 走看看