Linux进程间通信(信号量)

什么是信号量

      为了防止出现多个程序同时访问一个共享数据资源而引发的问题,需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区。信号量就可以提供这样一种访问机制。 信号量的本质是一种数据操作锁,是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步功能。

信号量的工作原理

   信号量能够进行的两种操作分别是:等待信号P(sv)和发送信号V(sv)
   ☆P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就将该进程挂起;

   ☆V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1。

Linux的信号量机制

   Linux提供的信号量接口有:

   semget函数

int semget(key_t key, int num_sems, int sem_flags);

      作   用:创建一个新信号量或取得一个已有信号量;

         参   数:key是键值,它要与已有的键值进行比较,已有的键值指在内核中已存在的其它信号量集合的键值;

                   num_sems指定需要的信号量数目,它的值几乎总是1;

                   sem_flags是一组标志,当想要当信号量不存在时创建一个新的信号量。IPC_CREAT | IPC_EXCL可以                          创建一个新的、唯一的信号量,如果信号量已存在,返回一个错误。

      返回值:如果成功,则返回信号量集合的IPC识别号;如果为-1,则出现错误;

    semop函数

int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);

       作   用:改变信号量的值;

       参   数:sem_id是由semget返回的信号量标识符;

                    num_sem_ops是说我们仅仅执行了一个操作;

                    sem_opa参数指向类型为sembuf的一个数组,这个结构在/inclide/linux/sem.h 中声明:

struct sembuf{  
    short sem_num; /* 在数组中信号量的索引值 */ 
    short sem_op;  /* 信号量操作值(正数、负数或0) */。  
    short sem_flg; /* 操作标志,通常为SEM_UNDO*/ 
}; 

        「SEM_UNDO当操作信号量(semop)时,sem_flg可以设置SEM_UNDO标识;SEM_UNDO用于将修改的信号           量值在进程正常退出(调用exit退出或main执行完)或异常退出(如段异常、除0异常、收到KILL信号等)时              归还给信号量,从而使另外一个进程可以继续工作,防止其他进程因为得不到信号量而发生“死锁现象”。                  为此一 般建议使用SEM_UNDO。

    若通过kill命令把其中一个进程杀死,且该进程还没有执行V操作释放资源。若使用SEM_UNDO标志,则操作系           统将自动释放该进程持有的信号量,从而使得另外一个进程可以继续工作。若没有这个标志,另外进程将P操               作永远阻塞。

      返回值:如果所有的操作都执行,则成功返回0;如果为-1,则出错。

    semctl函数

int semctl(int semid,int semnum, int cmd, union semun arg);

        作   用:控制信号量信息;

        参   数:cmd参数表示在集合上执行的命令(通常为SETVAL(用联合体中val成员的值设置信号量集合中单个信号量的值)或者IPC_RMID(从内核中删除信号量集合))

                      arg参数的类型为semun,这个特殊的联合体在 include/linux/sem.h中声明:

union semun{
	int val;                /* value for SETVAL */
	struct semid_ds *buf;   /* buffer for IPC_STAT & IPC_SET */
	ushort *array;          /* array for GETALL & SETALL */
	struct seminfo *__buf;  /* buffer for IPC_INFO */
	void *__pad;
};

使用信号量进行通信

   comm.h

    

   comm.c

     

     

     

     

   test_sem.c

     

     

   运行结果:

     

   分析:

     因为每个程序都在其进入临界区后和离开临界区前打印一个字符,所以每个字符是成对出现的。

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值