信号量及进程间通信

信号量

信号量 --- 线程间 有顺序的协调工作

信号量 (个数) --- 反映的是资源的数量
信号量的机制:来描述 可使用的资源的个数 

P操作 :表示 使用这个资源  资源个数减 1  
       p操作逻辑
      尝试获取资源,
      有资源可用,直接使用,资源个数减一 ,如果没有资源可用,此时等待 

V操作 : 表示 产生这个资源 , 资源个数加 1

      V操作逻辑
      释放一个资源
      如果此时有任务,在等待这个资源,这个资源直接给对应的任务 
      如果没有任务需要使用这个资源,此时将资源个数加1     

写线程  ---写资源 
        可以写数据 的条件 
        1.开始时 ,buf空的 
        2.读线程 读完了 

        P(写资源)

         V(读资源)

读线程 
       //buf充当读资源 
       //1.一开始,buf中没有数据可读的 
       2.写线程结束 
       
       P(读资源)   读操作 
       V(写资源)
       

框架:
    1. 信号量的定义     sem_t  sem //造了一类资源 
    2. 信号量的初始化   sem_init 
    3. 信号量的PV操作  (核心) sem_wait()/ sem_post()   ---生产者 消费者 模型 
    4. 信号量的销毁。   sem_destroy

    semaphore 
    1、信号量的定义 :
       sem_t          sem;
       信号量的类型     信号量的变量
   sem_t sem_w;
   sem_t sem_r;

 2、信号量的初始化:
        int sem_init(sem_t *sem, int pshared, unsigned int value);
        功能:将已经定义好的信号量赋值。
        参数:sem 要初始化的信号量
              pshared = 0 ;表示线程间使用信号量
                      !=0 ;表示进程间使用信号量
              value 信号量的初始值,一般无名信号量
              都是二值信号量,0 1 
              0 表示红灯,进程暂停阻塞
              1 表示绿灯,进程可以通过执行
        返回值:成功  0
                失败  -1;
   //写资源 
   sem_w 
   sem_init(&sem_w,0,1); //1 表示我有一个写资源可用 
   sem_t sem_r;
   sem_init(&sem_r,0,0);

3、信号量的PV 操作
       P ===》申请资源===》申请一个二值信号量 
       V ===》释放资源===》释放一个二值信号量

       P操作对应函数 ==》sem_wait();
       V操作对应函数 ==》sem_post();

    int sem_wait(sem_t *sem); //p操作 
    功能:
          判断当前sem信号量是否有资源可用。
          如果sem有资源(==1),则申请该资源,程序继续运行
          如果sem没有资源(==0),则线程阻塞等待,一旦有资源
          则自动申请资源并继续运行程序。

          注意:sem 申请资源后会自动执行 sem = sem - 1;
    参数:sem 要判断的信号量资源
    返回值:成功 0  ,失败 -1
    int sem_post(sem_t *sem); //V操作 
    功能:
          函数可以将指定的sem信号量资源释放
          并默认执行,sem = sem+1;
          线程在该函数上不会阻塞。
    参数:sem 要释放资源的信号量
    返回值:成功 0 ,失败 -1;

4、信号量的销毁
       int sem_destroy(sem_t *sem);
       功能:使用完毕将指定的信号量销毁
       参数:sem要销毁的信号量
       返回值:成功 0 ,失败  -1;

给线程1输入字符串,线程2输出字符串,用信号量保障两线程有序调用

创建三个线程使其有序输出字符串how are you

进程间通信

 通信的方式:  七种
  //同一主机
1、古老的通信方式      管道:无名管道    (1) ,有名管道    (2)
                                     信号  (3)

2、IPC对象通信 system v    BSD     suse fedora   kernel.org
        消息队列 (用的相对少,这里不讨论)   (4)
        共享内存(*) //最高效                (5)
        信号量集() //信号量                 (6)
//不同主机 
3、socket通信
        网络通信                            (7)

无名管道

函数pipe   创建一个管道

 int pipe(int pipefd[2]);  
 参数:    @pipefd //用来获取 管道的两端 //读端pipefd[0]   //写端pipefd[1]    ,其中为文件描述符

返回值: 成功 0 ,失败 -1 && errno  

管道的特点:
   1.管道大小 65536字节   64k 
   2.管道操作特点 
     数据读走之后,认为就没了

管道的读写规则:
    1.读端存在,写管道
      管道空:可以写数据
      管道满:会造成-->写阻塞 
    
    2.读端不存在,写管道
      系统会给进程发一个信号SIGPIPE(管道破裂)

    3.写端存在,读管道
      管道空,读不到数据,
      这时会造成读操作阻塞

    4.写端不存在,读管道 
      如果管道中有数据,则读取这些数据!
      如果没有数据,读操作不阻塞,立即返回!


父进程中通过管道传递信息到子进程

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值