Nonblock I/O 及其使用
来源:互联网 发布:广联达软件好学吗 编辑:程序博客网 时间:2024/06/07 05:28
这是个很有趣的topic,而且这个东东影响到了kernel/driver和application之间的交互。
首先要来说下这个概念的东东。 当应用程序被block后,这个程序就进入了sleep状态。有可能会block的地方有:
1. open
2. read
3. write
一般情况下,文件的读写是阻塞的,可以通过fcntl()函数来设置为非阻塞读写。且这一点需要driver的配合。
好,来看看一个实际的例子的片段。
driver部分:如果该文件设置了O_NONBLOCK,则直接返回-EAGAIN。
static ssize_t scull_p_read (struct file *filp, char __user *buf, size_t count,
loff_t *f_pos)
{
struct scull_pipe *dev = filp->private_data;
if (down_interruptible(&dev->sem))
return -ERESTARTSYS;
while (dev->rp == dev->wp) { /* nothing to read */
up(&dev->sem); /* release the lock */
if (filp->f_flags & O_NONBLOCK)
{
PDEBUG("nonblock version read/n" );
return -EAGAIN;
}
PDEBUG("/"%s/" reading: going to sleep/n", current->comm);
if (wait_event_interruptible(dev->inq, (dev->rp != dev->wp)))
return -ERESTARTSYS; /* signal: tell the fs layer to handle it */
/* otherwise loop, but first reacquire the lock */
if (down_interruptible(&dev->sem))
return -ERESTARTSYS;
}
/* ok, data is there, return something */
if (dev->wp > dev->rp)
count = min(count, (size_t)(dev->wp - dev->rp));
else /* the write pointer has wrapped, return data up to dev->end */
count = min(count, (size_t)(dev->end - dev->rp));
if (copy_to_user(buf, dev->rp, count)) {
up (&dev->sem);
return -EFAULT;
}
dev->rp += count;
if (dev->rp == dev->end)
dev->rp = dev->buffer; /* wrapped */
up (&dev->sem);
/* finally, awake any writers and return */
wake_up_interruptible(&dev->outq);
PDEBUG("/"%s/" did read %li bytes/n",current->comm, (long)count);
return count;
}
application部分:
使用fcntl()设置了O_NONBLOCK,这样在read的时候,就会立即返回。
而且再判断了返回值,EAGAIN表示需要再试。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
char buffer[4096];
int main(int argc, char **argv)
{
int delay = 1, n, m = 0;
int fd;
if (argc > 1)
delay=atoi(argv[1]);
fd = open("/dev/scullpipe0",O_RDWR );
fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
while (1) {
n = read(fd, buffer, 4096);
printf("return value from read is %d/n", n);
if (n >= 0)
m = write(1, buffer, n); /* stdout */
if ((n < 0 || m < 0) && (errno != EAGAIN))
break;
sleep(delay);
}
perror(n < 0 ? "stdin" : "stdout");
exit(1);
}
- Nonblock I/O 及其使用
- AVR 学习笔记------AVR的I/O端口及其使用
- I/O概述及其分类
- I/O设备及其分类
- 使用I/O
- Image I/O使用
- 常见的I/O模型及其区别
- 浅析I/O模型及其设计模式
- 5.1.I/O设备及其分类
- I/O 流的使用
- java I/O使用总结
- i/o使用,文件操作
- Java I/O 使用基本原则
- 初级的I/O使用.
- I/O流 使用举例
- 9.4. 使用 I/O 内存
- 单片机I/O口使用
- 文件I/O和标准I/O的使用
- Android通过共享用户ID来实现多Activity进程共享
- 多触摸学习
- call 方法的使用
- 用C#实现简单的FTP应用程序
- Number Sequence
- Nonblock I/O 及其使用
- JSCRIPT继承
- C# 中FtpWebRequest 类NetworkCredential多次连接认证的问题
- IE和Firefox的差异及解决方案
- BCB图像处理总结
- startActivityForResult的妙用
- GoBoard3D(WPF) 游戏规则
- 欢迎辞
- PHP 数组遍历 的差异(array_diff 的实现)