使用FIFO实现POSIX有名信号量

使用FIFO实现POSIX信号量算是一个《UNIX网络编程 卷二》中第十章的一个高级内容,其实数中仅仅是大致的实现了POSIX信号量中极为有限的一部分功能。书中重新写了sem_open函数、sem_unlink函数、sem_close函数、sem_wait函数和sem_post函数,为什么说使用FIFO仅仅实现了POSIX信号量中极为有限的一部分呢?我们需要从FIFO开始分析,分析完FIFO的性质之后这些问题就不难理解了。

首先FIFO是一个有名的半双工管道,这种有名管道的实现类似于队列,我们可以在其一端执行写入操作,另一端进行读取操作。虽然FIFO是UNIX系统中可以看得到的文件,但是要清楚向FIFO中读写数据并不需要经过磁盘IO,实际上数据仍然是写到内存中的。我们可以猜测一下FIFO的实现,既然IPC的一个设计要求就是高性能,而且FIFO是伴随进程持续的,那么为什么不把其映射到内中呢?在这里我们遇到了第一个问题,就是FIFO的持续性的问题,可知当最后一个进程(线程)关闭了FIFO时,FIFO中的数据将会被丢弃。想一想POSIX信号量,信号量是一个(至少)伴随内核持续的一种IPC。书中给出的思路是每次挂出信号量时向FIFO中写入一个字符,等待时从FIFO总读出一个字节。可以预见下面的问题,当第一个进程调用了我们实现的sem函数时,对于这个进程而言是没有什么影响的,当这个进程结束之后,另一个进程试图用sem_open函数打开信号量时貌似也没有什么问题,接下来我们调用sem_wait函数时就会发现进程在此处阻塞,原因就是当FIFO没有进程打开时里面的数据会被丢弃。这个问题需要我们特别的注意,下面还有一个问题是因为FIFO自身性质导致的。

当我们实现一个POSIX信号量时要注意了,使用open函数如果不指定不阻塞的话,那么进程或者线程会阻塞在open函数处,当我们不考虑实现sem_trywait时,我们需要用非阻塞的模式分别以读和写的模式打开FIFO,之后还需要关闭在读描述符上的非阻塞标记。其实在sem_open函数实现的过程中要注意的东西有很多,实现的大部分难度都集中在这里,我们不得不对不同的情况作出不同的处理,包括出错时要关闭打开的所有文件描述符并释放内存等。我们不能让函数返回一段静态内存,这样是不安全的。

接下来的问题就和FIFO没有多大的关系了,一个有关信号量是否有效的校验问题,当然书上给出的方法并不完美,在运行的时候很容易就导致程序的崩溃。不过这个检查又总是要比没有好一些吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值