您的位置:首页 > 运维架构 > Linux

Linux驱动程序学习备忘之四

2014-04-02 15:13 190 查看
继续向后面学习,接下去要看的就是阻塞和非阻塞编程。

我在书上看到这么一段程序,但我觉得好像哪里有点不对。最后看过内核源代码后才豁然开朗。

主要是down_interruptible()这个函数,网上普遍的解释如下

int down_interruptible(struct semaphore *sem)
//这个函数的功能就是获得信号量,如果得不到信号量就睡眠,此时没有信号打断,那么进入睡眠。但是在睡眠过程中可能被信号打断,打断之后返回-EINTR,主要用来进程间的互斥同步。


然后我就一直在琢磨,那它在睡眠中被对应的信号量唤醒后,那它会不会执行P操作了?

一开始我还以为会执行P操作的,但是源代码中是这么写着的

/**
* down_interruptible - acquire the semaphore unless interrupted
* @sem: the semaphore to be acquired
*
* Attempts to acquire the semaphore.  If no more tasks are allowed to
* acquire the semaphore, calling this function will put the task to sleep.
* If the sleep is interrupted by a signal, this function will return -EINTR.
* If the semaphore is successfully acquired, this function returns 0.
*/
int down_interruptible(struct semaphore *sem)
{
unsigned long flags;
int result = 0;

spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
result = __down_interruptible(sem);
spin_unlock_irqrestore(&sem->lock, flags);

return result;
}


在这个if中可以看出,P操作只在一开始判断到可以获取信号量的时候才会执行,一开始如果信号量已经被人占用,那么就只能进入睡眠,等到睡眠醒后,依然是没有获取信号量的,除非down_interruptible()再执行一遍。这个貌似在好多down()中都是这么一个写法。

在这一章的最后,讲了字符设备驱动程序对一些高级特性的实现

驱动实现non-seekable

1)在open功能函数中调用nonseekable_open(inode,filp)告知OS本设备不支持seek

int nonseekable_open(inode,filp)
{
filp->f_mode &= ~(FMODE_LSEEK|FMODE_PREAD|FMODE_PWRITE);
return 0;
}


2)将file_operations中的.llseek设置为no_llseek。no_llseek会向操作系统返回ESPIPE

loff_t no_llseek(struct file * file,loff_t offset,int origin)
{
return -ESPIPE;
}


驱动如何实现select

操作系统对select的实现

当用户程序调用select时,操作系统会依次轮询select中指定的所有文件描述符对应的设备,即调用所有设备驱动程序中的.poll函数

poll函数会做两件事

A)告知操作系统如果设备暂时不可用的话,进程应该阻塞在哪个等待队列上(输入还是输出)

B)根据设备的具体状况告知操作系统设备是否可用(信号量是否被占用等等)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: