学习嵌入式第二十七天

信号量的机制:
    
    1.信号量 --- 来描述 可使用的资源的个数 
    2.P操作 
      表示 使用这个资源  资源个数减 1  
      
      p操作逻辑
      尝试获取资源,
      有资源可用,直接使用,资源个数减一 
      如果没有资源可用,此时等待 
    3.V操作 
      表示 产生这个资源  资源个数加 1
       
      V操作逻辑
      释放一个资源
      如果此时有任务,在等待这个资源,这个资源直接给对应的任务 
      如果没有任务需要使用这个资源,此时将资源个数加1       
         
     
     考虑的时候,站在使用者的角度考虑 //生产者消费者模型
    
    
    站在a的角度考虑
       这块资源它什么时候能用    
    站在b的角度考虑
       这块资源它什么时候能用
    

    linux下的线程同步  ===》信号量机制 ===》semaphore.h   posix 
    sem_open();
    
    信号量的分类:
    1、信号无名量 ==》线程间通信
    2、有名信号量 ==》进程间通信

    框架:
    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、古老的通信方式
        管道:
           无名管道    (1)
           有名管道    (2)
        信号           (3)

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

管道: 

   无名管道 
     
     
   int pipe(int pipefd[2]);  
   功能:
       创建一个管道 
   参数:
     @pipefd //用来获取 管道的两端 //读端pipefd[0] 
                                   //写端pipefd[1]

   返回值:
      成功 0
      失败 -1 && errno  
      
管道的特点:
   1.管道大小 65536字节   64k 
   2.管道操作特点 
     数据读走之后,认为就没了 
     
     //写端存在,读端也存在 
     管道如果为空,此时可以一直写,直到写满     
     
     //写端存在,读端不存在 
     此时,写操作,会导致管道破裂 
     SIGPIPE //这个信号会使得程序结束 
     
     
     //写端存在,读管道 
     可以读管道,但是管道中如果没有数据了,此时读操作 阻塞 
     
     //写端不存在,读管道 
     可以读管道,但是管道中如果没有数据了,此时读操作 不阻塞 
    
    
    
    管道的读写规则:
    1.读端存在,写管道
      管道空:可以写数据
      管道满:会造成-->写阻塞 
    
    2.读端不存在,写管道
      系统会给进程发一个信号SIGPIPE(管道破裂)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值