当前位置 博文首页 > 文章内容

    多线程的互斥(下)——信号量

    作者: 栏目:未分类 时间:2020-08-08 14:01:16

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    信号量的概念

    -信号量是特殊的线程锁

    -信号量允许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 )