Linux 进程通信(System V) 第四节 ------>信号量

1.并不是IPC机制,它是一种提供不同进程之间或者是同一个进程的不同的线程之间的同步!
2.类型:
 
          <1>.二元信号:值为0或者1,1说明有一个可以资源,0说明此时正好再用,其他进程等待
                                    相当于是 P 和 V 问题...
                                   
            <2>.计数信号量:值在0和一个大于0的值之间,一般是可用的资源数量
           
            <3>.计数信号量集:由一个或多个信号量组成的集合,每一个都是计数信号量。一般在25个以上。
           
            >>>:
                  其使用就是我们知道的P/V操作一样,需要P是否有资源,如果P到,那么就是VALUE--,然后使用OK后还回来,也就是VALUE++,if申请不到资源就要阻塞自己!

3.信号量数据结构:
           
            #include<sys/sem.h>
            structsemid_ds                                                //!> semaphore iddescription
            {
                  structipc_perm            sem_perm;            //!> 操作权限结构体
                  struct sem                      sem_base;            //!> 设置信号量指针
                  ushort                              sem_nsems;            //!> 集合中信号量数量
                  time_t                              sem_otime;            //!> 最后一次(上一次)操作的时间
                  time_t                              sem_ctime;            //!> 上一次修改时间
            };
           
            #include<sys/ipc.h>
            structipc_perm                                                //!> ipc permission( IPC 的权限设置结构体)
            {
                  uid_t            uid;                                          //!> 所有者用户ID
                  gid_t            gid;                                          //!> 所有者组ID
                  uid_t            cuid;                                          //!> 创建者ID
                  gid_t            cgid;                                          //!> 创建者组ID
                  mode_t      mode;                                          //!> 读写权限
                  ulong_t      seq;                                          //!> 槽的使用序列号
                  key_t            key;                                          //!> IPC KEY
            };
         
              mode 低九位:
                                                  0400      用户可读.
                                                  0200      用户可写.

                                                  0040      组成员可读.
                                                0020      组成员可写.

                                                  0004      其他用户可读.
                                                  0002      其他用户可写.
           
           
            struct sem                                                                  //!> semapore
            {
                  ushort_t            semval;                                    //!> 信号值,非负
                  short                  sempid;                                    //!> 上一次对其进行成功操作的进程PID
                  ushort_t            semncnt;                                    //!> 等待semval增加(长)的进程数
                  ushort_t            semzcnt;                                    //!>等待semval=0(为0)的进程数     
            }
           
           
           
4.信号量的创建和操作:
           
            <1>.semget函数用来创建一个信号量集合或者访问一个已经存在的!
            #include<sys/types.h>
            #include<sys/ipc.h>
            #include<sys/sem.h>
           
            int semget( key_t key, int nsems, int oflag);
            参数:
                        nsems:信号量集合中的信号量个数(ATTENTION:if仅仅是访问一个EXIST的信号量集合,那么此值为0,因为一个信号量集合创建OK后,信号量数目不可改变! ) (但if是创建,那么肯定是一个大于0的数才是有意义的! )
                        oflag:值是SEM_R和SEM_A的组合( 读与写),也可以是IPC_CREAT和IPC_EXCL的按位或                                                           
                       
                        返回值:信号量标志( semid )
                       
                        创建信号量OK后,对于semid_ds的初始化为:
                                                                                                      sem_perm的uid和cuid为进程有效用户的ID,gid和cgid是进程有效用户的组ID
                                                                                                      oflag:参数sem_perm.mode中
                                                                                                      sem_otime = 0;
                                                                                                      sem_ctime = 当前时间
                                                                                                      sem_nsems = nsems;
                                                                                                     
            <2>.创建OK后就可以使用semop对信号量进行操作。
           
            int semop( int semid, struct sembuf * opsptr,size_t nops );
            参数:
                        struct sembuf
                        {
                              short            sem_num;                        //!> 信号编号
                              short            sem_op;                        //!> 信号操作
                              short            sem_flg;                        //!> 操作标志
                        };
           
                        nops:由指针opsptr指向的数组中元素个数(数组反应内容:给所指定的某个特定的信号量指定一个操作!通过sem_num知道此特定信号量 )
                 
            <3>.通过semctl函数对一个信号量进行各种操作:
           
            int semctl( int semid, int semnum, int cmd, ...);
            参数:
                        semid:要进行操作的信号量集
                        semnum:信号集中某个信号量( 0 ---> MAX - 1的取值 ),
                                                            可取为:GATVAL, SETVAL, GETNCNT, GETZCNT, GETPID

                        最后一个参数可选,取决于第三个参数:cmd
                        union semun
                        {
                              int                                     val;                        //!> 为了 SETVAL 使用
                              structsemid_ds            buf;                  //!>为了IPC_STAT使用      ( 用于取出值 )
                              ushort                            array;                  //!> 为GETALL和SETALL使用
                        };
                       
                        cmd 取值:
                                          IPC_STAT:指定联合体是semid_ds,放在buf中
                                          IPC_SET:按照buf中的数据设置此集合中的3个字段,即sem_perm结构体中的uid,gid,mode
                                          IPC_RMID:从系统中删除该信号量集合
                                          GETVAL:返回semnum的semval值
                                          SETVAL:设置semnum的semval值,由semun中的val指定
                                          GETPID:返回semnum的sempid值
                                          GETNCNT:返回semnum的semncnt值
                                          GETZCNT:返回semnum的semzcnt值
                                          GETALL:取集合上所有的信号量放在array中
                                          SEIALL:按照array中的值设置集合中的每个信号量的值
         

应用:信号量的使用是与“共享内存区”是连在一起的,所以在“进程通信的共享内存区中有具体的设计”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值