首页 / LINUX / linux驱动开发学习三:异步操作
linux驱动开发学习三:异步操作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了linux驱动开发学习三:异步操作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1480字,纯文字阅读大概需要3分钟。
内容图文
前面的队列以及锁都是基于阻塞是的操作。要实现同步,还可以通过信号也就是异步的方式来进行。例如在往文件的写入字符后,发送一个信号。捕捉到信号后执行动作。这样就不会造成阻塞,之前的阻塞性IO和POLL,是调用函数进去检查,条件不满足是造成阻塞。
应用层启动异步通知机制就三个步骤:
1 调用signal函数,让指定的信号SIGIO与处理函数sig_handle对应
2 指定一个进程作为文件的”属主(filp-owner)”, 这样内核才知道信号要发给哪个进程
3 在设备文件中添加FASYNC标志,驱动中就会调用xxx_fasync函数。
流程图如下:
在这里,命名为globalfifo_fasync
static const struct file_operations globalmem_fops={
.owner=THIS_MODULE,
.llseek=globalmem_llseek,
.read=globalmem_read_queue,
.write=globalmem_write_queue,
.unlocked_ioctl=globalmem_ioctl,
.open=globalmem_open,
.release=globalmem_release,
.fasync=globalfifo_fasync,
};
globalfifo_fasync函数实现如下,当文件的模式被设置成FASYNC的时候,将会调用这个函数
static int globalfifo_fasync(int fd,struct file *filp,int mode)
{
struct globalmem_dev *dev=filp->private_data;
return fasync_helper(fd,filp,mode,&dev->async_queue);
}
在 globalfifo_fasync中实际调用的是fasync_add_entry。
(1) 申请一个fasync_struct结构体。可以看到这个结构体手链表形式。fa_fd关联了设备文件fd参数
struct fasync_struct {
spinlock_t fa_lock;
int magic;
int fa_fd;
struct fasync_struct *fa_next; /* singly linked list */
struct file *fa_file;
struct rcu_head fa_rcu;
};
(2) 调用fasync_insert_entry将新分配的fasync_struct插入到fasync列表中去。代码如下,如果能在fasync列表中找到对应的filp文件。则直接返回。如果没有找到,则将new插入到fapp的最前面。插入方法new->fa_fd = fd; new->fa_next = *fapp; 和前面介绍的列表插入方法是一样的。
4 等操作完成后,比如写完成,此时可以读取数据了,则通过kill_fasync释放一个信号。代码如下
实际起作用的是kill_fasync_rcu函数,在这个里面,遍历列表中所有的数据,找到owner以及fd。然后发送相应的信号
5 等操作完后fasync_remove_entry将异步队列清空
原文:https://www.cnblogs.com/zhanghongfeng/p/12286298.html
内容总结
以上是互联网集市为您收集整理的linux驱动开发学习三:异步操作全部内容,希望文章能够帮你解决linux驱动开发学习三:异步操作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。