down_interruptible如何理解

时间:2022-07-19 15:14:58

       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);

 

希望对你有点帮助~,完全摘抄的,希望没侵犯版权~~~