程序员首页投稿(暂停使用,暂停投稿)

使用System V信号量同步引起的Interrupted sy

2016-09-20  本文已影响0人  HHFCodeRv

使用System V信号量不是那么熟练. 写了一个Monitor监测线程, 一个实际执行的Product线程.
本来的想法两个线程一个一个的调, 但是我忘了把另外一个线程注释掉了.然后就这么产生了.

先看Monitor代码:

然后gdb去调试的时候, 总是出现

error

我一开始以为我的程序出错了, 因为我System V信号量用的不是很熟练, 但是我发现我写的没有错呀, 都是这样用的呀. 一番查找下, 我就确定我这样用是没错的, 就去Google了一下, 发现了真相.

原来GDB在调试的时候是会发生这种情况的.具体的内容自己查看

GDB 引起Interrupted system call原因:

文档中还说明了, GDB使用内核中断的方式监测线程库, 例如线程的创建、销毁等情况. 如果当这些情况发生时,尽管程序在我们的预想中不能结束, 但是系统调用可能提前结束, 就导致出现Interrupted system call

尽管文档没有详细说明引起的原因, 但是已经够了. 我知道了我的程序出错的原因, 我把另外一个线程注释掉, 然后再调这个线程, 这没有这个问题发生了.

PS:如果不注释掉另外一个线程, 但是不用GDB去跑, 也不会发生Interrupted system call, 这和文档说明的情况是一样的.

add:2016-9-22
今天才发现原来《UNIX网络编程--进程间通信》[P230]中也有说明
"当一个线程被投入睡眠以等待某个信号量操作完成之时(我们将看到该线程既可以等待改信号量的值变为0, 也可等待它变为大于0), 如果它捕获了一个信号, 那么其信号处理程序的返回将中断引起睡眠的semop函数, 该函数于是返回一个EINTR错误.按照UNPv1的术语定义, semop是需被所捕获的信号中断的慢系统调用"

解决方法:

解决方法其实很简单,就是我们要接受一下Interrupted system call(EINTR)信号就可以了
比如上面的代码,修改如下

semop用法

int semop(int semid, struct sembuf *opstr, size_t nops)
semval: 信号量当前值

struct sembuf { short sem_num; short sem_op; sem_flag; }

代码

有关详细封装的代码请查看我的github

上一篇下一篇

猜你喜欢

热点阅读