ldd3中的p70 p72 页介绍了scull 设备驱动方法的read和write的实现,在中间有两句是这样写的:
if(down_interruptible(&dev->sem))
return -ERESTARTSYS;
但这里没有给出任何解释,这里在csdn上面找了一些资料,并且百度了一下信号量的概念,加上大学课堂的回忆PV操作
这里把资料给整合起来,方便以后复习总结。
1.提问贴
参见:http://bbs.csdn.net/topics/300092023
if(down_interruptible(&dev->sem))
return -ERESTARTSYS;
其中dev->sem是用于实现互斥的信号量
请问这两行代码是什么意思?因为down_interruptible正常情况下是返回0的,这里它不是正常返回,到底是因为没能拿到信号量,还是因为被中断了呢?
另外,顺便问一下:能否用通俗的话讲讲ERESTARTSYS,EAGAIN到底表示什么?
回答如下:http://hi.baidu.com/whandsome/blog/item/3834e32a9994692cd52af1f9.html
2.自查篇
在内核源码中:include\asm-arch\Semaphore.h 中定义了这些函数
关键的结构:
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
};
关键的函数:
static inline void down(struct semaphore * sem);
static inline void up(struct semaphore * sem);
static inline int down_interruptible(struct semaphore * sem);
static inline int down_trylock(struct semaphore * sem)
在include\linux\Errno.h 中
/* Should never be seen by user programs */
#define ERESTARTSYS 512
#define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
可以看出这个标准错误号为512,上面注释说,用户程序不可见
在\include\asm-generic\errno-base.h中定义了标准错误号码1-34
在\include\asm-generic\errno.h中定义了标准错误号码35-131,中间的58号有点特殊,是个宏来着
#define ERESTART 85 /* Interrupted system call should be restarted */ 中间的85号错误,看起来更像是个用户代码可用的错误号
中断的系统调用应该被重启(自己翻译的)
3.网络篇
http://blog.csdn.net/JackWang_cm/article/details/7062362
http://blog.csdn.net/herowang701/article/details/6656420
摘抄如下:
down_interruptible()是处理信号量的函数。
他的返回值有三种 1. “0” 2. “-ETIME” 3.“-EINTR”
0 代表正常返回
-ETIME 等待超时
-EINTR 中断
函数的运作方式:
如果sem->count >0 (信号量允许访问)
返回0 (正常返回)
否则进行等待
在函数实现中:
调用__down_common()
__down_common()中有for循环
当有中断信号时 返回 -EINTR ,当等待超时时返回 -ETIME.
信号量变为可访问状态时 返回0
此外
在 http://download.csdn.net/detail/shaoguangleo/2719175中的总结如下
15、信号量与互斥体,头文件asm/semaphore.h。一个信号量本质上是一个整数值,它和一对函数联合使用,这对函数通常成为P和V。希望进入临界区的进程将在相关信 号 量上调用P。如果信号量的值大于0,则该值会减一,而进程得以继续;如果信号量的值为0,进程必须等待直到其他人释放该信号量。对信号量的解锁通过调用 V完成;该函数对信号量的值做加一操作,并在必要时唤醒等待的进程。
信号量的初始化:
DECLARE_MUTEX(name);//一个称为name的信号量被初始化为1
DECLARE_MUTEX_LOCKED(name);一个称为name的信号量被初始化为0
P函数称为down:
void down(struct semaphore *sem);//down减少信号量的值,并在必要时一直等待
int down_interruptible(struct semaphore *sem);//down_interruptible完成相同工作,它允许等待在某个信号量上的用户空间进程可被用户中断
int down_trylock(struct semaphore *sem);//down_trylock不会休眠,如果信号量在调用时不可获得,会立即返回一个非零值
作为通常的规则,我们不应该使用非中断操作。使用down_interruptible需要小心,如果操作被中断,该函数会返回非零值,而调用者不会拥有该信号量。对down_interruptible的正确使用需要始终检查返回值,并作成相应响应。
V函数称为up:
void up(struct semaphore *sem);
希望对你有点帮助~,完全摘抄的,希望没侵犯版权~~~