非阻塞io

1.对比

阻塞io的例子:scanf从终端获取输入时,如果不输入程序就会一直停在那; 对一个已经有写锁的文件请求读时, 会一直空等直到前面的进程释放锁...

非阻塞的例子:读取文件内容, 如果文件当前因加锁无法访问则立即出错返回

2.非阻塞io设置方法

a.调用open函数时, 指定O_NONBLOCK标志

open(filename,O_RDWR,O_NONBLOCK)

b.已经打开的fd, 调用fcntl将fd的O_NONBLOCK标志打开

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h> char buf[500000]; void set_fl(int fd,int flags){
int val;
if((val=fcntl(fd,F_GETFL,0))<0){
perror("fcntl F_GETFL error");
exit(1);
}
val|=flags;
if(fcntl(fd,F_SETFL,val)<0){
perror("fcntl F_SETFL error");
exit(1);
}
} void clr_fl(int fd,int flags){
int val;
if((val=fcntl(fd,F_GETFL,0))<0){
perror("fcntl F_GETFL error");
exit(1);
}
val &= ~flags;
if(fcntl(fd,F_SETFL,val)<0){
perror("fcntl F_SETFL error");
exit(1);
}
} int main(){
int ntowrite,nwrite;
char *ptr; ntowrite=read(STDIN_FILENO,buf,sizeof(buf));
fprintf(stderr,"read %d bytes\n",ntowrite); set_fl(STDOUT_FILENO,O_NONBLOCK); ptr=buf;
while(ntowrite>0){
errno=0;
nwrite=write(STDOUT_FILENO,ptr,ntowrite);
fprintf(stderr,"nwrite=%d,errno=%d\n",nwrite,errno); if(nwrite>0){
ptr += nwrite;
ntowrite -= nwrite;
}
} clr_fl(STDOUT_FILENO,O_NONBLOCK);
return 0;
}

执行 ./a.out < /etc/services 2>stderr.out

查看stderr.out文件会发现write函数出现了很多次相同错误,

在centos上, 出错的errno=11, Resource temporarily unavailable

书本上测试的为errno=35, Resource deadlock avoided

从结果上看, 在写入stdout时, 由于终端缓冲的原因没办法一次write完成, 所以分成很多次去写

因为设置了O_NONBLOCK, 所以提交write任务后, 如果当前终端还在处理上一个循环的write, 则本次write立即返回并设置errno

记录锁(文件锁).

1.记录锁用于多进程对文件编辑的保护

2.锁函数

int fcntl(int fd, int cmd, struct flock *lock);

cmd = F_GETLK,测试能否建立一把锁
cmd = F_SETLK,设置锁
cmd = F_SETLKW, 阻塞设置一把锁 struct flock {
short l_type; /* 锁的类型: F_RDLCK, F_WRLCK, F_UNLCK */
short l_whence; /* 加锁的起始位置:SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* 加锁的起始偏移,相对于l_whence */
off_t l_len; /* 上锁的字节数*/
pid_t l_pid; /* 已经占用锁的PID(只对F_GETLK 命令有效) */
/*...*/
};

3.锁的继承和释放

a.进程结束后, 进程所建立的锁全部释放

b.fork产生的子进程不继承父进程的锁

c.执行exec后, 新程序可以继承原执行程序的锁

4.建议锁和强制锁

建议锁:只关注fcntl加锁函数, open/read/write可以无视文件是否加锁

强制锁:read/write/open函数执行时都要检查文件是否加锁

值得注意的是, 强制锁的实现依赖系统

下面的程序运行二个实例, 第二个实例会在lockfile那一步报错

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h> int lockfile(int fd){
struct flock fl;
fl.l_type=F_WRLCK;
fl.l_start=0;
fl.l_whence=SEEK_SET;
fl.l_len=0;
return(fcntl(fd,F_SETLK,&fl));
}
#define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
int main(){
int fd;
char *filename="./test.txt";
struct stat statbuf;
if((fd=open(filename,O_RDWR|O_CREAT,FILE_MODE))<0){
perror("open error");
exit(1);
}
if(write(fd,"abcdef",6) != 6){
perror("write error");
exit(1);
}
/*
* if(fstat(fd,&statbuf)<0){
* perror("fstat error");
* exit(1);
* }
*
* if(fchmod(fd,(statbuf.st_mode & ~S_IXGRP) | S_ISGID) <0){
* perror("fchmod error");
* exit(1);
* }
*/
if(lockfile(fd)<0){
perror("lockfile error");
exit(1);
}
while(1){
;
}
}

非阻塞io与记录锁的更多相关文章

  1. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  2. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  3. Python_阻塞IO、非阻塞IO、IO多路复用

    0.承上 进程: 计算机里最小的资源分配单位: 数据隔离, 利用多核,数据不安全. 线程: 计算机中最小的CPU调度单位: 数据共享,GIL锁,数据不安全. 协程: 线程的一部分,是有用户来调度的; ...

  4. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  5. Redis——非阻塞IO和队列

    Redis是个高并发的中间件,但是确实是单线程.而且,Nginx.Node.js等也是单线程的.Redis通过非阻塞IO(IO多路复用)处理那么多的并发客户端连接,并且,由于Redis所有的数据都在内 ...

  6. Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO

    Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...

  7. 阻塞IO、非阻塞IO、同步IO、异步IO等

    https://www.cnblogs.com/zingp/p/6863170.html 阅读目录 1 基础知识回顾 2 I/O模式 3 事件驱动编程模型 4 select/poll/epoll的区别 ...

  8. Linux下的非阻塞IO(一)

    非阻塞IO是相对于传统的阻塞IO而言的. 我们首先需要搞清楚,什么是阻塞IO.APUE指出,系统调用分为两类,低速系统调用和其他,其中低速系统调用是可能会使进程永远阻塞的一类系统调用.但是与磁盘IO有 ...

  9. 【python】-- 事件驱动介绍、阻塞IO, 非阻塞IO, 同步IO,异步IO介绍

    事件驱动介绍 一.前言 通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求: (2)每收到一个请求,创建一个新的线程,来处理该请求: (3)每收 ...

随机推荐

  1. Flips测试类(page43)

    测试用例:所用java类: StdOut,StdIn , Counter, StdRandom, public class Flips { public static void main(String ...

  2. HTTPS的工作原理

    参考自<图解HTTP> 果壳网http://www.guokr.com/post/114121/ HTTPS的工作原理 增加了一层:HTTPS流程:应用层 HTTP->SSL/TLS ...

  3. python备忘录

    本文主要是记录一下python,比较详尽的python学习资料: Python学习笔记_王纯业 http://pan.baidu.com/s/1eQrDEYA 部分有详细的博文链接 1.字符串: 切片 ...

  4. JNA参数传递问题,Java数组

    版权声明:本文为博主原创文章,未经博主允许不得转载. 本文主要讲述使用JNA模拟结构体并将结构体数组作为参数传递给对应的方法. C语言结构体定义如下: typedef struct Rect { in ...

  5. jQuery.Hotkeys - lets you watch for keyboard events anywhere in your code supporting almost any key combination

    About jQuery Hotkeys is a plug-in that lets you easily add and remove handlers for keyboard events a ...

  6. (转)分布式缓存GemFire架构介绍

    1什么是GemFire GemFire是一个位于应用集群和后端数据源之间的高性能.分布式的操作数据(operational data)管理基础架构.它提供了低延迟.高吞吐量的数据共享和事件分发.Gem ...

  7. ubuntu下安装git,sublime,nodejs

    用的是VMware10.0版本的虚拟机,很早之前下载的今天就直接用了,安装挺简单记得需要一个序列号.在这里:http://mirrors.163.com/ubuntu-releases/15.04/u ...

  8. maxlength属性在textarea里奇怪的表现

    HTML5给表单带来了很多改变,比如今天要说的maxlength,这个属性可以限制输入框输入的最大字字符数,更方便的是对于粘贴的内容也能够根据字符数自动截断. 最近就接到这要一个需求,限制用户最多输入 ...

  9. 安装Apache(httpd服务)

    安装Apache(httpd服务) ① 移动所有压缩包到root文件夹下(root的家) ② 解压httpd压缩包(.tar.gz) 使用tar指令解压.tar.gz压缩包 tar 指令 -zxf : ...

  10. CSS样式表与格式布局

    样式表 CSS(Cascading Style Sheets  层叠样式表),作用是美化HTML网页. 内联样式表: 例:<p style="font-size:10px;" ...