zoukankan      html  css  js  c++  java
  • 多线程的互斥(下)——信号量

    信号量的概念

    -信号量是特殊的线程锁

    -信号量允许N个线程同时访问临界资源

    -Qt中直接支持信号量(QSemaphore)

    线程锁是用来保护临界资源的,每个线程锁每次只允许一个线程进行访问临界资源。

    QSemaphore sem(1)定义了一个信号量,并且N的值为1,意味着一次只允许一个线程去访问临界资源。

    sem.acquire()当前线程尝试着获取这个特殊的线程锁,首先到该函数中查看n的值是不是大于0的,如果是的话,就可以获取这把特殊的线程锁。如果n的值为0,那就必须等待。 

    再论生产消费者的问题:

    在前面的实验中已经做过一个生产者,一个消费者,一个仓库。在本课程中实现n个生产者,n个消费者,n个仓库。如何做到并发高效性呢,此时就需要使用QSemphore信号量了。

    #include <QCoreApplication>
    #include <QThread>
    #include <QDebug>
    #include <QSemaphore>
    
    const int SIZE = 5; //用来定义仓库的个数
    unsigned char g_bufer[SIZE] = {0};
    QSemaphore g_sem_free(SIZE);  //表示5个仓库都是空闲的
    QSemaphore g_sem_used(0);   //初始值为0,表示有多少个仓库已经被使用了
    
    class Producer : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                int value = qrand()%100;
    
                g_sem_free.acquire();
                for(int i=0; i<SIZE; i++)
                {
                    if( !g_bufer[i] )
                    {
                        g_bufer[i] = value;
                        qDebug() << objectName() << "generate (" << i << "," << value << ")" << endl;
                        break;
                    }
                }
    
                g_sem_used.release();
                sleep(2);
            }
        }
    };
    
    class Consumer : public QThread
    {
    protected:
        void run()
        {
            while(true)
            {
                g_sem_used.acquire();
                for(int i=0; i<SIZE; i++)
                {
                    if( g_bufer[i] )
                    {
                        int value = g_bufer[i];
                        g_bufer[i] = 0;
                        qDebug() << objectName() << "consume (" << i << "," << value << ")" <<endl;
                        break;
                    }
                }
                g_sem_free.release();
                sleep(2);
    
            }
        }
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Producer p1;
        Producer p2;
        Producer p3;
    
        Consumer c1;
        Consumer c2;
    
        p1.setObjectName("p1");
        p2.setObjectName("p2");
        p3.setObjectName("p3");
        c1.setObjectName("c1");
        c2.setObjectName("c2");
    
    
        p1.start();
        p2.start();
        p3.start();
        c1.start();
        c2.start();
    
        return a.exec();
    }

    打印结果如下:

    "p1" generate ( 1 , 41 )
    
    "p3" generate ( 2 , 41 )
    
    "p2" generate ( 0 , 41 )
    
    "c2" consume ( 1 , 41 )
    
    "c1" consume ( 0 , 41 )
    
    "p2" generate ( 0 , 67 )
    
    "p3" generate ( 1 , 67 )
    
    "p1" generate ( 3 , 67 )
    
    "c1" consume ( 1 , 67 )
    
    "c2" consume ( 0 , 67 )
    
    "p2" generate ( 0 , 34 )
    
    "p3" generate ( 1 , 34 )
    
    "p1" generate ( 4 , 34 )
    
    "c1" consume ( 1 , 34 )
    
    "c2" consume ( 0 , 34 )
    
    "p2" generate ( 0 , 0 )
    
    "p3" generate ( 0 , 0 )
    
    "c1" consume ( 2 , 41 )
    
    "c2" consume ( 3 , 67 )
    
    "p1" generate ( 0 , 0 )
    
    "p2" generate ( 0 , 69 )
    
    "c1" consume ( 0 , 69 )
    
    "p3" generate ( 0 , 69 )
    
    "c2" consume ( 0 , 69 )
    
    "p1" generate ( 0 , 69 )
    
    "c1" consume ( 0 , 69 )
    
    "p2" generate ( 0 , 24 )
    
    "c2" consume ( 0 , 24 )
    
    "p3" generate ( 0 , 24 )
    
    "c1" consume ( 0 , 24 )
    
    "p1" generate ( 0 , 24 )
    
    "c2" consume ( 0 , 24 )
    
    "p2" generate ( 0 , 78 )
    
    "c1" consume ( 0 , 78 )
    
    "p3" generate ( 0 , 78 )
    
    "c2" consume ( 0 , 78 )
    
    "p2" generate ( 0 , 58 )
    
    "c1" consume ( 0 , 58 )
    
    "p1" generate ( 0 , 78 )
    
    "c2" consume ( 0 , 78 )
    
    "p3" generate ( 0 , 58 )
    
    "c1" consume ( 0 , 58 )
    
    ""p2" generate ( 0 , 62 )
    
    c2" consume ( 4 , 34 )
    
    "p1" generate ( 1 , 58 )
    
    "c1" consume ( 0 , 62 )
    
    "p3" generate ( 0 , 62 )
    
    "c2" consume ( 0 , 62 )
    
    "p1" generate ( 0 , 62 )
    
    "c1" consume ( 0 , 62 )
    
    "p2" generate ( 0 , 64 )
    
    "c2" consume ( 0 , 64 )
    
    "p3" generate ( 0 , 64 )
    
    "c1" consume ( 0 , 64 )
    
    "p1" generate ( 0 , 64 )
    
    "c2" consume ( 0 , 64 )
    
    "p3" generate ( 0 , 5 )
    
    "c1" consume ( 0 , 5 )
    
    "p2" generate ( 0 , 5 )
    
    "c2" consume ( 0 , 5 )
    
    "p1" generate ( 0 , 5 )
    
    "c1" consume ( 0 , 5 )
    
    "p3" generate ( 0 , 45 )
    
    "c2" consume ( 0 , 45 )
    
    "p2" generate ( 0 , 45 )
    
    "c1" consume ( 0 , 45 )
    
    "p1" generate ( 0 , 45 )
    
    "c2" consume ( 0 , 45 )
    
    "p3" generate ( 0 , 81 )

  • 相关阅读:
    NS2 nam中节点及数据流颜色设置
    JSF简单介绍
    深入浅出谈开窗函数(一)
    BZOJ2440(全然平方数)二分+莫比乌斯容斥
    怎样在SharePoint管理中心检查数据库架构版本号、修补级别和修补程序的常规监控
    Java实现BASE64编解码
    博弈 个人 见解
    【剑指offer】第一个仅仅出现一次的字符
    cocos2d基础篇笔记四
    SSL连接建立过程分析(1)
  • 原文地址:https://www.cnblogs.com/-glb/p/13457567.html
Copyright © 2011-2022 走看看