【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("爸爸放入一个苹果!\n");
                 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("妈妈放入一个橙子!\n");
                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("儿子吃了一个苹果!\n");
                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("女儿吃了一个橙子!\n");
                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);
}
    原文作者:Love_Hulidear
    原文地址: https://blog.csdn.net/lovecodeless/article/details/24919511
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞