zoukankan      html  css  js  c++  java
  • 【C/C++多线程编程之七】pthread信号量

    多线程编程之信号量


         Pthread是 POSIX threads 的简称。是POSIX的线程标准
             相互排斥量用来处理一个共享资源的同步訪问问题,当有多个共享资源时,就须要用到信号量机制。

             信号量机制用于保证两个或多个共享资源被线程协调地同步使用。信号量的值相应当前可用资源的数量。

             1.信号量samaphore):

            信号量机制通过信号量的值控制可用资源的数量。线程訪问共享资源前,须要申请获取一个信号量,假设信号量为0。说明当前无可用的资源,线程无法获取信号量,则该线程会等待其它资源释放信号量(信号量加1)。假设信号量不为0。说明当前有可用的资源,此时线程占用一个资源,相应信号量减1。

            举例:
            停车场有5个停车位,汽车可使用停车位。在这里5个停车位是共享的资源。汽车是线程。開始信号量为5,表明此时有5个停车位可用。一辆汽车进入停车场前。先查询信号量的值,不为0表明有可用停车位,汽车进入停车场并使用一个停车位。信号量减1。表明占用一个停车位,可用数降低。
           
               2.信号量基本函数
             #include <semaphore.h>
    初始化信号量:
            int sem_init(sem_t *sem, int pshared, unsigned int val);
            该函数第一个參数为信号量指针,第二个參数为信号量类型(一般设置为0)。第三个为信号量初始值。第二个參数pshared为0时,该进程内全部线程可用。不为0时不同进程间可用。
    信号量减1:
            int sem_wait(sem_t *sem);
            该函数申请一个信号量。当前无可用信号量则等待,有可用信号量时占用一个信号量。对信号量的值减1。


    信号量加1:
            int sem_post(sem_t *sem);

            该函数释放一个信号量。信号量的值加1。


    销毁信号量:
            int sem_destory(sem_t *sem);

            该函数销毁信号量。       

            3.牛刀小试
            採用信号量机制,解决苹果橙子问题:一个能放N(这里N设为3)个水果的盘子。爸爸仅仅往盘子里放苹果。妈妈仅仅放橙子。女儿仅仅吃盘子里的橙子,儿子仅仅吃苹果。
            採用三个信号量:
            1.sem_t empty:信号量empty控制盘子可放水果数,初始为3,由于開始盘子为空可放水果数为3。
            2.sem_t  apple ;信号量apple控制儿子可吃的苹果数。初始为0。由于開始盘子里没苹果。
            3.sem_t orange;信号量orange控制女儿可吃的橙子是。初始为0,由于開始盘子里没橙子。

    注:相互排斥量work_mutex仅仅为printf输出时可以保持一致,可忽略。
     
    #include 
    #include 
    #include 
    #include 
    #pragma comment(lib, "pthreadVC2.lib")     //必须加上这句
    sem_t empty;  //控制盘子里可放的水果数
    sem_t apple;  //控制苹果数
    sem_t orange; //控制橙子数
    pthread_mutex_t work_mutex;                    //声明相互排斥量work_mutex
    void *procf(void *arg) //father线程
              { 
                 while(1){
                     sem_wait(&empty);     //占用一个盘子空间,可放水果数减1
                     pthread_mutex_lock(&work_mutex);     //加锁
                     printf("爸爸放入一个苹果!
    ");
                     sem_post(&apple);     //释放一个apple信号了。可吃苹果数加1
                     pthread_mutex_unlock(&work_mutex);   //解锁
                     Sleep(3000);
                 }
    
               }
    void *procm(void *arg)  //mother线程
              { 
                while(1){
                    sem_wait(&empty);
                    pthread_mutex_lock(&work_mutex);     //加锁
                    printf("妈妈放入一个橙子!
    ");
                    sem_post(&orange);
                    pthread_mutex_unlock(&work_mutex);   //解锁
                    Sleep(4000);
                }
               }
    void *procs(void *arg)  //son线程
              { 
                while(1){
                    sem_wait(&apple);       //占用一个苹果信号量。可吃苹果数减1 
                    pthread_mutex_lock(&work_mutex);     //加锁
                    printf("儿子吃了一个苹果!
    ");
                    sem_post(&empty);       //吃了一个苹果,释放一个盘子空间,可放水果数加1
                    pthread_mutex_unlock(&work_mutex);   //解锁
                    Sleep(1000);
                }
               }
    void *procd(void *arg)  //daughter线程
              { 
                while(1){
                    sem_wait(&orange);
                    pthread_mutex_lock(&work_mutex);     //加锁
                    printf("女儿吃了一个橙子!
    ");
                    sem_post(&empty);
                    pthread_mutex_unlock(&work_mutex);   //解锁
                    Sleep(2000);
                }
    
               }
    
    void main()
    { 
        pthread_t father;  //定义线程
        pthread_t mother;
        pthread_t son;
        pthread_t daughter;
    
        sem_init(&empty, 0, 3);  //信号量初始化
        sem_init(&apple, 0, 0);
        sem_init(&orange, 0, 0);
    	pthread_mutex_init(&work_mutex, NULL);   //初始化相互排斥量
    
        pthread_create(&father,NULL,procf,NULL);  //创建线程
        pthread_create(&mother,NULL,procm,NULL);
        pthread_create(&daughter,NULL,procd,NULL);
        pthread_create(&son,NULL,procs,NULL);
    
        Sleep(1000000000);
    }
    


  • 相关阅读:
    P1144 最短路计数 题解 最短路应用题
    C++高精度加减乘除模板
    HDU3746 Teacher YYF 题解 KMP算法
    POJ3080 Blue Jeans 题解 KMP算法
    POJ2185 Milking Grid 题解 KMP算法
    POJ2752 Seek the Name, Seek the Fame 题解 KMP算法
    POJ2406 Power Strings 题解 KMP算法
    HDU2087 剪花布条 题解 KMP算法
    eclipse创建maven项目(详细)
    maven的作用及优势
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10090552.html
Copyright © 2011-2022 走看看