多线程编程之信号量

     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);
}

【C/C++多线程编程之七】pthread信号量的更多相关文章

  1. 多线程编程(一)-Semaphore(信号量)的使用

    Semaphore的介绍 单词Semaphore的中文含义就是信号.信号系统的意思,此类的主要作用就是限制线程并发的数量. 举个例子,一个屋子里有10个人,但只有一个窄门可以出去,这个窄门一次最多只能 ...

  2. 多线程编程-- part 9 信号量:Semaphore

    Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量 ...

  3. C#多线程编程のSemaphore(信号量,负责协调各个线程)

    Semaphore负责协调线程,可以限制对某一资源访问的线程数量 这里对SemaphoreSlim类的用法做一个简单的例子: namespace WpfApplication6 { /// <s ...

  4. 【C/C++多线程编程之十】pthread线程私有数据

    多线程编程之线程私有数据      Pthread是 POSIX threads 的简称.是POSIX的线程标准.         线程同步从相互排斥量[C/C++多线程编程之六]pthread相互排 ...

  5. pthread多线程编程的学习小结

    pthread多线程编程的学习小结  pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写     程序员必上的开发者服务平台 —— DevSt ...

  6. ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程

    为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...

  7. 为什么对多线程编程这么怕?pthread,sem,mutex,process

    转自http://blog.chinaunix.net/uid-20788636-id-1841334.html 1.线程创建和退出创建线程实际上就是确定调用该线程函数的入口点,这里通常使用的函数是p ...

  8. Linux多线程编程-信号量

    在Linux中.信号量API有两组.一组是多进程编程中的System V IPC信号量.另外一组是我们要讨论的POSIX信号量. 这两组接口类似,但不保证互换.POSIX信号量函数都已sem_开头,并 ...

  9. Linux下多线程编程-信号量

    今天来谈谈线程的同步--信号量. 首先来看看一些概念性的东西: 如进程.线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行:B依言执行,再将结果给 ...

随机推荐

  1. 【机器学习】机器学习入门02 - 数据拆分与测试&算法评价与调整

    0. 前情回顾 上一周的文章中,我们通过kNN算法了解了机器学习的一些基本概念.我们自己实现了简单的kNN算法,体会了其过程.这一周,让我们继续机器学习的探索. 1. 数据集的拆分 上次的kNN算法介 ...

  2. gulpfile.js demo

    var config = require("./build.config") //获取build.config.js文件里的内容 var gulp = require(" ...

  3. Cat- Linux必学的60个命令

    1.作用 cat(“concatenate”的缩写)命令用于连接并显示指定的一个和多个文件的有关信息,它的使用权限是所有用户. 2.格式 cat [options] 文件1 文件2…… 3.[opti ...

  4. [转]WPF自定义控件之带倒计时的按钮--Button

    1.说明 之前做过一个小项目,点击按钮,按钮进入倒计时无效状态,计时完成后,恢复原样,现在就实现该效果---带倒计时的按钮 2.效果 1)正常状态               2)MouseOver( ...

  5. 后缀自动机SAM

    某神犇:"初三还不会后缀自动机,那就退役吧!" 听到这句话后,我的内心是崩溃的. 我还年轻,我还不想退役--于是,我在后来,努力地学习后缀自动机. 终于,赶在初三开学前,我终于学会 ...

  6. Django项目:CRM(客户关系管理系统)--65--55PerfectCRM实现CRM客户报名状态颜色变化

    # kingadmin.py # ————————04PerfectCRM实现King_admin注册功能———————— from crm import models #print("ki ...

  7. 使用cmd查看windows端口占用情况,并关闭应用

    在做开发的时候常常会遇到端口被占用的问题,下面是我在网上找的比较好用的一种关闭占用端口进程的方法 1.在运行中输入cmd打开dos命令窗口,比如我想找到端口8888对应的PID(通过PID找到相应的进 ...

  8. $(...).live is not function

    项目中引入了一个插件,但是调用的时候就报了$(...).live is not function 上网搜索了一下live方法在1.9中被删除了,因为平时自己用的时候就用on的方法,没用过live,所以 ...

  9. 用sqoop抽取oracle 表到hbase的例子

    sqoop import \-Doraoop.disabled=true \--connect jdbc:oracle:thin:@"(DESCRIPTION=(ADDRESS=(PROTO ...

  10. UVa 12034 Race 递推?

    一开始是想排列组合做的,排列组合感觉确实可以推出公式,但是复杂度嘛.. dp[i][j]表示有i只马,j个名次的方法数,显然j<=i,然后递推公式就很好写了,一只马新加进来要么与任意一个名次的马 ...