/**
*此实例涉及到线程的挂起与竞态,字符IO的堵塞与非堵塞
*/ struct scull_pipe {
wait_queue_head_t inp, outp;
char *buffer, *end;
char *rp, wp;
//int buffersize;
int nreaders, nwriters;
struct fasync_struct *async_queue;
struct semaphore sem;
struct cdev cdev;
}; /**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
* /inlcude/linux/kernel.h
*
*/
/*#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
*/ static ssize_t scull_p_read (struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
/*得到指向结构体scull_pipe的指针*/
/*
(void *private_data)private_data指针是file结构体中的成员之一,
它是跨系统挑用是保存状态信息的非常有用的资源,这里我们
在open阶段使用container_of函数得到指向结构体scull_pipe的指针并将private_data指向它
记住要在release方法中释放其内存
*/ struct scull_pipe *dev = filp->private_data; /*使用信号量限制在同一时刻只有一个线程执行*/
/*若被中断则返回非零值,若无法撤销任何用户可见的修改return - EINTR*/
if (down_interruptible(&dev->sem))
return -ERESTARTSYS; while (dev->rp == dev->wp)
{
up_interruptible(&dev->sem); /*判断用户是否设置了非堵塞IO*/
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN; /*将线程挂起*/
if (wait_event_interruptible(&dev->inp, dev->rp != dev->wp))
return -ERESTARTSYS; if (down_interruptible(&dev->sem))
return -ERESTARTSYS;
} /*min函数在Linux内核/include/linux/kernel.h中*/
if (dev->wp > dev->rp)
count = min(count, (size_t) (dev->wp - dev->rp));
else
count = min(count, (size_t) (dev->end - dev->rp)); if (copy_to_user(buffer, dev->rp, count))
{
up_interruptible(&dev->sem);
return -EFAULT;
} dev->rp += count;
if (dev->rp == dev->end)
dev->rp = dev->buffer up_interruptible(&dev->sem);
wake_up_interruptible(&dev->outp);
return count;
} /*个人仿照上方写的管道写操作代码*/
static ssize_t scull_p_write (struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
struct scull_pipe *dev = filp->private_data; if (down_interruptible(&dev->sem))
return -ERESTARTSYS; /*判断条件有所不同*/
while (strlen(dev->buffer) && dev->rp == dev->wp)
{
up_interruptible(&dev->sem); if (filp->f_flags & O_NONBLOCK)
return -EAGAIN; if (wait_event_interruptible(&dev->outp))
return -ERESTARTSYS; down_interruptible(&dev->sem);
} if (dev->wp > dev->rp)
count = min(count, (size_t) (dev->end - dev->wp));
else
count = min(count, (size_t) (dev->rp - dev->wp - 1)); if (copy_form_user(dev->wp, buffer, count))
{
up_interruptible(&dev->sem);
return -EFAULT;
} dev->wp += count;
if (dev->wp == dev->end)
dev->wp = dev->buffer; up_interruptible(&dev->sem);
wake_up_interruptible(&dev->inp);
return count;
}

高级字符驱动之堵塞与非堵塞IO的更多相关文章

  1. Linux下文件的堵塞与非堵塞对部分系统调用的影响

    1.基本概念 所谓的堵塞,即内核在对文件操作I/O系统调用时.假设条件不满足(可能须要产生I/O),则内核会将该进程挂起.非堵塞则是发现条件不满足就会马上返回. 此外须要注意的是非堵塞并非轮询.不然就 ...

  2. IO模式——同步(堵塞、非堵塞)、异步

    为什么IO模式非常重要?由于现代的计算机和操作系统的架构决定了CPU是稀缺资源,大家都要来一起竞争.而IO(特别是网络相关的IO)的速度往往较慢.所以怎样进行IO就有了多种模式,包含同步.异步.堵塞. ...

  3. 网络编程----堵塞、非堵塞和同步、异步IO

    我是学渣.但我想进步. 本文是面试我的牛人问我的.你知道什么是堵塞.非堵塞和同步.异步IO么?自觉得是分布式系统程序猿的我居然不知道.学习吧. 首先介绍堵塞IO和非堵塞IO: 堵塞IO:是指说程序等待 ...

  4. systemverilog中堵塞和非堵塞事件以及同步

    一.SV中非堵塞事件 module test; event ev1, ev2; //belong to logic function part always@(ev1) $display(" ...

  5. Java IO:同步、非堵塞式IO(NIO)

    转载请注明出处:jiq•钦's technical Blog 引言 JDK1.4中引入了NIO,即New IO,目的在于提高IO速度.特别注意JavaNIO不全然是非堵塞式IO(No-Blocking ...

  6. 《网络编程》非堵塞 I/O

    概述 在前面文章中,我们介绍了 I/O 的五种模型<I/O 模型>.从那里能够知道,非堵塞式的 I/O 是进程调用 I/O 操作时.若数据未准备就绪.则马上返回一个 EWOULDBLOCK ...

  7. linux 下同步异步,堵塞非堵塞的一些想法

    补充: 发现一个更好的解释样例:同步是一件事我们从头到尾尾随着完毕.异步是别人完毕我们仅仅看结果. 堵塞是完毕一件事的过程中可能会遇到一些情况让我们等待(挂起).非堵塞就是发生这些情况时我们跨过. 比 ...

  8. Linux 文件描写叙述符设置为非堵塞的方法

    通过fcntl设置文件描写叙述符属性 fcntl即F_SETFL,F_GETFL的使用,设置文件的flags,堵塞设置成非堵塞,非堵塞设置成堵塞(这连个在server开发中能够封装为基本函数) 1.获 ...

  9. 《Java并发编程实战》第十五章 原子变量与非堵塞同步机制 读书笔记

    一.锁的劣势 锁定后假设未释放.再次请求锁时会造成堵塞.多线程调度通常遇到堵塞会进行上下文切换,造成很多其它的开销. 在挂起与恢复线程等过程中存在着非常大的开销,而且通常存在着较长时间的中断. 锁可能 ...

随机推荐

  1. Sublime Text 3 多行游标

    选中要修改的地方ctrl+D ,要跳过不需要修改的选中的就用ctrl+k+d 选中要修改的地方ctrl+D,选中所有要修改的 alt+f3 ctrl+A  ,然后ctrl+shift+L 按住shif ...

  2. express知识点

    本篇文章主要内容 1.用Express在系统文件夹内搭建一个服务器 2.Express的路由(来自 Express 文档) 3.Express的中间件(这才是关键) 4.Express的一些零碎的知识 ...

  3. 6、python数据类型之元组(dict)

    字典字典的每个元素就是一个键值对,格式如下key:value{key1:value1,key2:value2,......} 1.创建 dict_eg = { "name":&qu ...

  4. myeclipse9.0安装svn插件

    先得保证myeclipse9.0是可以正常使用的吧. 第一步当然是从网上下载SVN插件啦.myeclipse9.0集成的eclipse版本是属于3.x,所以下载eclipse3.x系列的SVN插件. ...

  5. ros indigo install

    http://wiki.ros.org/cn/indigo/Installation/Ubuntu

  6. (转)linux 中特殊符号用法详解

    linux 中特殊符号用法详解 原文:https://www.cnblogs.com/lidabo/p/4323979.html # 井号 (comments)#管理员  $普通用户 脚本中 #!/b ...

  7. asp.net 在IIS上配置出现的一些问题

    1.可能会遇到一下图的错无.请求的内容似乎是脚本.因而将无法由静态文件处理程序来处理---大概的原因是应用程序池选择错误了.如第二幅图如此解决即可 解决方案如下两个图所示. 我遇到了以上的问题之后能也 ...

  8. Spring之Quartz定时任务和Cron表达式详解

    1.定时业务逻辑类 public class ExpireJobTask { /** Logger */ private static final Logger logger = LoggerFact ...

  9. meterpreter > ps

    meterpreter > ps Process List============ PID PPID Name Arch Session User Path --- ---- ---- ---- ...

  10. Check Point R80 Security Management

    平台: CentOS 类型: 虚拟机镜像 软件包: Security Management basic software security 服务优惠价: 按服务商许可协议 云服务器费用:查看费用 立即 ...