APUE 学习笔记(九) 高级I/O
1. 非阻塞I/O
2. fcntl记录锁
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */
off_t l_start; /* offset in bytes, relative to l_whence */
short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_len; /* length in bytes, 0 means lock to EOF */
pid_t l_pid; /* returned with F_GETLK */
};
#include <fcntl.h>
int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;
lock.l_type = type;
lock.l_start = offset;
lock.l_whence = whence;
lock.l_len = len;
int ret = fcntl(fd, cmd, &lock);
return ret;
}
如果两个进程相互等待对方持有并且锁定的资源时,则这两个进程处于死锁状态
3. select
#include <select.h>
int select(int maxfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
中间三个参数 readfds, writefds, exceptfds是指向描述符集的指针,每个描述符集存放在一个fd_set中:

这三个参数指针任意一个可以为空指针,表示对相应状态并不关心。如果三个指针都是空指针,则select提供了比sleep更精确的计时器,因为sleep只能等待整数秒,
而select的struct timeval可以精确到微秒
int FD_ISSET(int fd, fd_set* set);
void FD_CLR(int fd, fd_set* set);
void FD_SET(int fd, fd_set* set);
void FD_ZERO(fd_set* set);
select的第一个参数maxfds是三个描述符集中最大的fd数值加1,也可以将此参数设置为FD_SETSIZE,表明最大的描述符数
fd_set readset, writeset;
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(, &readset);
FD_SET(, &readset);
FD_SET(, &writeset);
FD_SET(, &writeset);
select(, &readset, &writeset, NULL, NULL);

因为描述符编号从0开始,所以要在最大描述符编号值加1,第一个参数实际上就是要检查的描述符数(从描述符0开始)
4. readn和writen
int readn(int fd, char* ptr, size_t n)
{
size_t nleft = n;
int nread = ;
while (nleft > ) {
if ((nread = read(fd, ptr, nleft)) < ) {
if (nleft == n) {
return -;
} else {
break;
}
} else if (nread == ) {
break;
}
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
int writen(int fd, char* ptr, size_t n)
{
size_t nleft = n;
int nwrite = ;
while (nleft > ) {
if ((nwrite = write(fd, ptr, nleft)) < ) {
if (nleft == n) {
return -;
} else {
break;
}
} else if (nwrite == ) {
break;
}
nleft -= nwrite;
ptr += nwrite;
}
return n - nleft;
}
5. 存储映射I/O mmap
#include <sys/mman.h>
void* mmap(void* addr, size_t len, int prot, int flag, int fd, off_t off);
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h> int main(int argc, char* argv[])
{
int fdin = ;
int fdout = ;
char* src = NULL;
char* dst = NULL;
struct stat statbuf;
if (argc != ) {
fprintf(stderr, "usage: %s <fromfile> <tofile>\n", argv[]);
return ;
}
if ((fdin = open(argv[], O_RDONLY)) < ) {
fprintf(stderr, "cannot open %s for reading\n", argv[]);
}
if ((fdout = open(argv[], O_RDWR | O_CREAT | O_TRUNC)) < ) {
fprintf(stderr, "cannot creat %s for writing\n", argv[]);
}
if (fstat(fdin, &statbuf)) {
fprintf(stderr, "fsat error\n");
} if (lseek(fdout, statbuf.st_size - , SEEK_SET) == -) {
fprintf(stderr, "lseek error\n");
}
if (write(fdout, "", ) != ) {
fprintf(stderr, "write error\n");
} if ((src = mmap(, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, )) == MAP_FAILED) {
fprintf(stderr, "mmap error for input\n");
} if ((dst = mmap(, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, )) == MAP_FAILED) {
fprintf(stderr, "mmap error for output\n");
}
memcpy(dst, src, statbuf.st_size);
munmap(src, statbuf.st_size);
munmap(dst, statbuf.st_size);
return ;
}
APUE 学习笔记(九) 高级I/O的更多相关文章
- APUE 学习笔记(十) 高级I/O
1. Unix IPC(InterProcess Communication) 同一主机的各个进程间的IPC:管道.FIFO.消息队列.信号量.共享存储器 不同主机上的各个进程间IPC:socket套 ...
- Hadoop学习笔记(7) ——高级编程
Hadoop学习笔记(7) ——高级编程 从前面的学习中,我们了解到了MapReduce整个过程需要经过以下几个步骤: 1.输入(input):将输入数据分成一个个split,并将split进一步拆成 ...
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...
- Go语言学习笔记九: 指针
Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...
- APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause
转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...
- APUE学习笔记3_文件IO
APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...
- matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色
一起来学matlab-matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 < ...
随机推荐
- Ubuntu编译Android源码过程中的空间不足解决方法
Android源码一般几十G,就拿Android5.0来说,下载下来大概也有44G左右,和编译产生的文件以及Ubuntu系统占用的空间加起来,源码双倍的空间都不够有.编译源码前能分配足够的空间再好不过 ...
- redis的一个bug
清楚redis缓存的时候,出现以下问题: (error) MISCONF Redis is configured to save RDB snapshots, but is currently not ...
- 记住密码功能 JS结合JQuery 操作 Cookie 实现记住密码和用户名!
// 记住密码功能 JS结合JQuery 操作 Cookie 实现记住密码和用户名! var username = document.getElementById("username&quo ...
- tomcat如何登录Server Status、Manager App、Host Manager
启动tomcat后,访问127.0.0.1会进入如下页面 版权声明:本文为博主原创文章,未经博主允许不得转载. 原文地址:https://www.cnblogs.com/poterliu/p/9602 ...
- MySQL中CONCAT()的用法
MySQL中CONCAT()的用法 在日常开发过程中,特别是在书写接口的时候,经常会遇到字符串拼接的情况,比如在返回图片数据时,数据库里往往存储的是相对路径,而接口里一般是存放绝对地址,这就需要字符串 ...
- 【网络基础】【TCP/IP】私有IP地址段
私有IP地址段 Class A:10.0.0.0 - 10.255.255.255 Class B:172.16.0.0 - 172.31.255.255 Class C:192.168.0. ...
- jQuery将物体居中,并且转换显示和隐藏
今天来给大家贴一段代码,代码的作用就是利用jQuery将物体居中,并且转换显示和隐藏: 首先建立一个div标签并且写好css样式,具体如下 然后我想要的效果是当我点击了button这个按钮,test可 ...
- django知识分支_1
django知识分支 1.Cookie工作流程: 浏览器向服务器发出请求,服务器接收到浏览器的请求进行处理,服务器设置一个cookie发送给浏览器,浏览器将cookie保存,当需要再次登录的时候,浏览 ...
- set 方法总结整理
#!/usr/bin/env python __author__ = "lrtao2010" #Python 3.7.0 集合常用方法 #集合是无序的,元素不能重复,元素只能是数字 ...
- AOP面向切面编程笔记
1.AOP概念:Aspect Oriented Programming 面向切面编程 2.作用:本质上来说是一种简化代码的方式 继承机制 封装方法 动态代理 …… 3.情景举例 ①数学计算器接口[Ma ...