进程间通信——信号量

一、进程间通讯——信号量

信号量:信号量实现的是一种类似于计数器的功能,用于为多个进程提供对共享数据对象的访问。主要是用于实现进程间的互斥和同步。
临界资源:同一时刻仅能被一个进程访问的资源。
原子操作:不能被中断的操作。
       为了获取共享资源,进程需要执行下列操作:
(1)测试控制该资源的信号量
(2)若此信号量为正,则表示进程可以使用该资源。在这种情况下,进程会将信号量值减1,表示使用了一个资源单位;
(3)否则,若此信号量值为0,则进程进入休眠状态,直至信号量值大于0,。进程被唤醒后,它会返回至步(1);
当进程不再使用由一个信号量控制的共享资源时,该信号量值加1,。如果有进程正在休眠等待此信号量,则唤醒它们;

二、信号量的控制结构

       为了正确地实现信号量,信号量值的测试及减1应当是原子操作。为此信号量有一个在内核实现的控制结构。这个控制结构在创建信号量成功后,由内核产生。其结构声明位于头文件bits/sem.h中
内核为每个信号量集合维护着一个semid_ds 结构:
struct semid_ds
{
  struct ipc_perm  sem_perm;   //许可权限结构
  unsigned  short  sem_nsems;//信号量集中的信号量个数,linux系统可以对一个信号量集进行操作好和控制
  time_t  sem_otime;//最后一次semop操作的时间
  time_t  sem_ctime;//最后一次调用semctl 改变信号量的时间
       ···
       ···
       ···  
};
每个信号量由一个无名结构表示,它只少包含下列成员:
struct {
 unsigned short  semval;//信号量的值(>=0)
 pid_t                  sempid;//
 unsigned  short  semncnt;
 unsigned  short  semzcnt;
};

三、信号量的操作

1、创建:  首先需要通过调用函数semget来获取一个信号量ID
  int  semget( key_t  key,int  nsems, int  flag);      
                                                                   //返回值:若成功,返回信号量ID;若出错,返回-1;
                   key_t  key   //键值,唯一标识一个信号量
                   int  nsems   //信号量集中信号量的个数
                   int  flag       //创建信号量标志。主要包含两方面的信息:一是访问权限信息,该权限信息将初始化信号量控制结构中的sem_perm权限结构;二、创建标志,主要的创建标志包括IPC_CREAT、IPC_EXCL等

在信号量创建成功以后,就可以通过信号量操作实现进程的互斥和同步。
2、P、V操作:
        #include <sys/sem.h>
       int semop(int semid, struct sembuf  semoparray[ ] , size_t  nops);
                                                                    //返回值:若成功,返回0;若出错,返回-1;
     参数说明:
            int semid  :输入参数,信号量集的标识符。该标识符是通过semget返回的
            size_t  nops :输入参数,操作的信号量个数。每次semop调用可以对一个信号量集中的多个信号量进行操作
           struct sembuf  semoparray[ ] :参数 semoparray是一个指针,它指向一个由sembuf结构表示的信号量操作数                                                            组:该参数表明了对该信号量集操作的详细情况;
      struct sembuf{
                              unsigned short    sem_num;   //信号集中信号量的编号(0~nsems-1)
                              short                    sem_op;  //具体操作(+1或-1)
                              short                    sem_flg;//信号量的操作标志 IPC_NOWAIT,SEM_UNDO
                           }
3、信号量控制      
             在进行信号量操作时,经常需要对信号量进行控制,如设置信号量的值、获取信号量的值等。linux系统提供了semctl函数完成对信号量的控制。
         int   semtcl ( int semid,   int  semnum,   int cmd,······)  
    参数说明:
             int semid  :输入参数,信号量集的标识符。该标识符是通过调用semget返回的
             int  semnum:输入参数,信号量的编号。信号量在信号量集中的索引
             int cmd: 输入参数,信号量控制命令
             ······  :输入参数,控制命令参数。对于不同的控制命令,其参数格式是不同的。为了满足这一需求,该参数     使用了联合,其原型如下;
              union semun{
                                      int      val;//用于SETVAL控制命令。整型变量,用于设置信号量的值
                                      struct  semid_ds  *buf;//用于IPC_STAT和IPC_SET控制命令。指向semid_ds结构指针,用于                                                                            获取或者设置信号量控制结构。
                                      unsigned  short  *array;//用于GETALL和SETALL控制命令。指向短整型数组的指针,用于获                                                                              取或者信号量集的值
                                  };

四、管理系统上所有信号量的命令
        1、查看系统所有的信号量集:   ipcs  -s
           2、删除系统中的信号量集:    ipcrm    -s    semid




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值