高级字符驱动之堵塞与非堵塞IO
/**
*此实例涉及到线程的挂起与竞态,字符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的更多相关文章
- Linux下文件的堵塞与非堵塞对部分系统调用的影响
1.基本概念 所谓的堵塞,即内核在对文件操作I/O系统调用时.假设条件不满足(可能须要产生I/O),则内核会将该进程挂起.非堵塞则是发现条件不满足就会马上返回. 此外须要注意的是非堵塞并非轮询.不然就 ...
- IO模式——同步(堵塞、非堵塞)、异步
为什么IO模式非常重要?由于现代的计算机和操作系统的架构决定了CPU是稀缺资源,大家都要来一起竞争.而IO(特别是网络相关的IO)的速度往往较慢.所以怎样进行IO就有了多种模式,包含同步.异步.堵塞. ...
- 网络编程----堵塞、非堵塞和同步、异步IO
我是学渣.但我想进步. 本文是面试我的牛人问我的.你知道什么是堵塞.非堵塞和同步.异步IO么?自觉得是分布式系统程序猿的我居然不知道.学习吧. 首先介绍堵塞IO和非堵塞IO: 堵塞IO:是指说程序等待 ...
- systemverilog中堵塞和非堵塞事件以及同步
一.SV中非堵塞事件 module test; event ev1, ev2; //belong to logic function part always@(ev1) $display(" ...
- Java IO:同步、非堵塞式IO(NIO)
转载请注明出处:jiq•钦's technical Blog 引言 JDK1.4中引入了NIO,即New IO,目的在于提高IO速度.特别注意JavaNIO不全然是非堵塞式IO(No-Blocking ...
- 《网络编程》非堵塞 I/O
概述 在前面文章中,我们介绍了 I/O 的五种模型<I/O 模型>.从那里能够知道,非堵塞式的 I/O 是进程调用 I/O 操作时.若数据未准备就绪.则马上返回一个 EWOULDBLOCK ...
- linux 下同步异步,堵塞非堵塞的一些想法
补充: 发现一个更好的解释样例:同步是一件事我们从头到尾尾随着完毕.异步是别人完毕我们仅仅看结果. 堵塞是完毕一件事的过程中可能会遇到一些情况让我们等待(挂起).非堵塞就是发生这些情况时我们跨过. 比 ...
- Linux 文件描写叙述符设置为非堵塞的方法
通过fcntl设置文件描写叙述符属性 fcntl即F_SETFL,F_GETFL的使用,设置文件的flags,堵塞设置成非堵塞,非堵塞设置成堵塞(这连个在server开发中能够封装为基本函数) 1.获 ...
- 《Java并发编程实战》第十五章 原子变量与非堵塞同步机制 读书笔记
一.锁的劣势 锁定后假设未释放.再次请求锁时会造成堵塞.多线程调度通常遇到堵塞会进行上下文切换,造成很多其它的开销. 在挂起与恢复线程等过程中存在着非常大的开销,而且通常存在着较长时间的中断. 锁可能 ...
随机推荐
- POJ1032 Parliament
题目来源:http://poj.org/problem?id=1032 题目大意:给定一个正整数N(5<=N<=1000),将N拆为若干个不同的数使得它们的乘积最大(找到一组互不相等,和为 ...
- DHCP原理和配置
在大型网络中,会有大量的主机和设备需要获取ip地址和网络参数,为了解决手动配置的工作量大.ip冲突问题,因此需要使用DHCP(dynamic host configuration protocol). ...
- 如何理解javascript中的同步和异步
javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要 ...
- LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.Fo ...
- postgresql 导出csv格式的数据后使用excel打开中文乱码的问题
两种方法: 1>使用excel 的自文本导入功能,具体方法: 1) 打开 Excel 2) 执行“数据”->“自文本” 3) 选择 CSV 文件,出现文本导入向导 4) 选择“分隔符号”, ...
- Spark最简安装
该环境适合于学习使用的快速Spark环境,采用Apache预编译好的包进行安装.而在实际开发中需要使用针对于个人Hadoop版本进行编译安装,这将在后面进行介绍. Spark预编译安装包下载——Apa ...
- DevOps的工程化
孙敬云 --Worktile高级系统架构师,WTC成员 1.研发的困境 互联网的环境 互联网这个环境比较特别,包括现在不只是互联网,就算是被互联网赋能的这些“互联网+”的企业也在改变,用户在发生变化, ...
- &&运算符和||运算符的优先级问题 专题
public class SyntaxTest { @Test public void test() { System.out.println(true || true && fals ...
- JS文本框输入限制
1上面的文本框只能输入数字代码(小数点也不能输入): CODE: <input onkeyup="this.value=this.value.replace(/\D/g,'')&quo ...
- [技术交流ppt]babel7中preset-env的优化使用
备注 pdf在这里