linux 内核创建信号量,Linux内核信号量和定时器问题请教:

正在学习用户态线程和内核态定时器的使用,有个问题请教大家:

我在用户空间建立了一个线程,内核做一个字符驱动模块,通过ioctl调用来不断读取内核定时器有没有

到期。在设备结构体里面加了一个信号量,在open调用的时候把信号量拿到,使用一个内核定时器,在内

核定时器到期的处理函数里面释放信号量,这样用户线程调ioctl的时候就获取不到信号量了,等定时器

超时了,就会释放信号量,这样ioctl就返回到用户空间了,可是下次再调用ioctl的时候就不等待信号量了,不知道为什么??

不知道这样做行不行,看书上好像都是两个内核线程间用信号量来通信,请大家指教,谢谢!

void timer_handle(void)

{

int i = 0;

mod_timer(&KDA_devp->s_timer,jiffies + HZ * 5);  /*重新改变定时器的超时时间*/

up(&KDA_devp->sem);  /*释放信号量,ioctl调用可以获取到该信号量*/

}

int KDA_open(struct inode *inode, struct file *filp)

{

struct KDA_dev *dev; /* device information */

dev = container_of(inode->i_cdev, struct KDA_dev, cdev);

filp->private_data = dev; /* for other methods */

init_timer(&KDA_devp->s_timer);

KDA_devp->s_timer.function = &timer_handle;

KDA_devp->s_timer.expires = jiffies + HZ * 5;

add_timer(&KDA_devp->s_timer); /*添加(注册)定时器*/

down_interruptible(&dev->sem); /*获取信号量*/

return 0;

}

int KDA_ioctl(struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long arg)

{

int err = 0;

int isr_num = 100;

struct KDA_dev *dev = filp->private_data;

printk("want to get sem n");

down_interruptible(&dev->sem);

switch(cmd)

{

case  1 :

printk("the case 1 n");

break;

case 2 :

printk("the case 2 n");

break;

case 3 :

__put_user(KDA_devp->ISR_flag, (int __user *)arg);

break;

default:

printk("the default case  n");

}

}

|

我个人觉得你这样做应该能实现你要的效果,但是逻辑上有点问题,理由如下:

1、信号量适用于进程间通信,而你这里实际上只有一个进程,即用户态创建的进程(你写成了线程)。这个进程和内核之间进行通过驱动接口进行数据交流,这个过程中并没有引入新的进程。其实简单化来看:这个模型的工作就是在进程里面先down()了一下,然后再up()一下,在down和up这段时间间隔内,轮询的查看信号量是否可用。但是信号量的真正作用确是用于进程间的通信,所以说你的效果应该能实现,但是逻辑上有点问题。

2、再分析下你这个模型,轮询的查看,这个很浪费CPU的资源。而根据你的设计,似乎用condition更合适一些。即先down()一下,然后用户态的进程就在那里阻塞着,什么时候定时器超时了,这个时候再产生一个condition,通知用户态的进程:我完事了,到你了。这时候用户态的进程再执行其他的操作。这样似乎效率更高一些。逻辑上也合理一些。

以上只是个人分析,未必全面,欢迎拍砖。

PS:这个确实是个挺不错的问题!

|

一般性思路: 应用程序调用驱动,通常在驱动里加入同步机制,例如用信号量加条件变量。

有数据需要应用程序处理时,驱动就唤醒应用程序,否则使应用程序睡眠(挂起)。这种异步的做法比较节省资源,比应用程序轮询高效得多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值