系统函数、系统调用

系统函数

open/close函数

函数原型

man 2 open

// open, creat - open and possibly create a file or device
// The argument flags must include one of the following access modes:
// O_RDONLY, O_WRONLY, or O_RDWR.
// 或者 O_APPEND O_CREAT O_EXCL O_TRUNC(清空文件)
int open(const char * pathname, int flags);
  • 头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// --> 简写为
#include <unistd.h>
  • demo
#include <stdio.h>
#include <fcntl.h> // O_RDONLY的头文件
#include <unistd.h> int main()
{
int fd;
fd = open("./dict", O_RDONLY | O_CREAT);
// 创建文件指定权限,8进制数
fd = open("./dict", O_RDONLY | O_CREAT, 0644);
printf(fd);
close(fd);
return 0;
}

read/write函数

ssize read(int fd, void *buf, size_t count);
ssize write(int fd, const void *buf, size_t count);

read参数

  • fd:文件描述符
  • buf:存放数据的缓冲区
  • count:缓冲区的大小

read返回值:

  • success:读到的字节数
  • fail:-1,设置errno

write返回值:

  • success:写入的字节数

  • error:-1

实现cp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> int main(int argc, char *argv[])
{
char buf[1024];
int len = 0;
int fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1)
{
perror("open argv1 error");
exit(1); // stdlib
}
// 打开文件,如果没有就创建,如有就清空
int fd2 = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0664); while((len = read(fd1, buf, 1024))!=0)
{
if(len < 0)
{
perror("read error!");
exit(1);
}
write(fd2, buf, len);
} close(fd1);
close(fd2); return 0;
}

跟踪系统调用

$ strace ./readWrite
read(-1, 0x7ffd53164ea0, 1024) = -1 EBADF (Bad file descriptor)
write(3, "", 18446744073709551615) = -1 EFAULT (Bad address)
read(-1, 0x7ffd53164ea0, 1024) = -1 EBADF (Bad file descriptor)
write(3, "", 18446744073709551615) = -1 EFAULT (Bad address)
read(-1, 0x7ffd53164ea0, 1024) = -1 EBADF (Bad file descriptor)
write(3, "", 18446744073709551615) = -1 EFAULT (Bad address)
read(-1, 0x7ffd53164ea0, 1024) = -1 EBADF (Bad file descriptor)
write(3, "", 18446744073709551615) = -1 EFAULT (Bad address)

库函数

fopen/fclose

fgetc/fputc

FILE *fp, *fp_out;
int n;
fp = fopen("./dict.txt", "rw");
if (fp == NULL) { perror("fopen error");
exit(1);
}
fp_out = fopen("dict.cp", "w");
if (fp_out == NULL) {
perror("fopen error");
exit(1);
}
while ((n = fgetc(fp)) != EOF) {
fputc(n, fp_out);
}
fclose(fp);
fclose(fp_out);

文件描述符

文件描述符指向文件结构体.

PCB(进程控制块) :本质是结构体,成员是文件描述符,文件描述符:01/2/3...

一个进程快最多打开1024个文件,第一个文件是stdin, 2->stdout, 3 ->stderr

阻塞、非阻塞

阻塞:当读取设备文件、网络文件。读取常规文件不会阻塞。

设备目录:

  • /dev/tty 【终端设备】

阻塞示例:

void block() {
char buf[10];
// 读取是个字节
int n = read(STDIN_FILENO, buf, 10);
if (n < 0) {
perror("read STDIN_FILENOO");
exit(1);
}
write(STDOUT_FILENO, buf, 10);
}

当以非阻塞的方式读取文件(设备文件或者网络文件),并且文件为空时,open函数返回-1,并且将errno 设置为 EAGAIN or EWOULDBLOCK

tryagain:
n = read(fd, buf, 10);
if(n<0)
{
if(errno!= EAGAIN)
{
perror("read /dev/tty");
exit(1);
}
else
{
write(STDOUT_FILENO, "try again!", strlen("try again!"));
sleep(2);
goto tryagain;
}
}

IO、阻塞和非阻塞、目录的更多相关文章

  1. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  2. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  3. 网络IO之阻塞、非阻塞、同步、异步总结

    网络IO之阻塞.非阻塞.同步.异步总结 1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一 ...

  4. IO操作概念。同步、异步、阻塞、非阻塞

    “一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作. 同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO. 阻塞IO和非阻塞IO的区别在于第 ...

  5. IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

    IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇) 当你发现自己最受欢迎的一篇blog其实大错特错时,这绝对不是一件让人愉悦的事. <IO - 同步,异步,阻塞,非阻塞 >是我在开始学习e ...

  6. IO中同步、异步与阻塞、非阻塞的区别

    一.同步与异步同步/异步, 它们是消息的通知机制 1. 概念解释A. 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例如si ...

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

    一.同步与异步同步/异步, 它们是消息的通知机制 1. 概念解释A. 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例如si ...

  8. 阻塞与非阻塞IO step by step

    谈到IO,阻塞.非阻塞,异步.同步是绕不开的话题.说实话,我也没搞清楚,网上查了许多资料,大家众说纷纭,一种比较靠谱的说法是:”在处理 IO 的时候,阻塞和非阻塞都是同步 IO,使用使用了特殊的API ...

  9. 阻塞与非阻塞的IO网络读写

    看我之前的文章就知道,一般对于网络读的socket,都会加上O_NONBLOCK,非阻塞的选项. int setnonblocking(int fd) { int old_option = fcntl ...

随机推荐

  1. Java连载66-数组的两种初始化方式

    一.数组 1.数组中存储元素的类型是统一的,每一个元素在内存中所占用的空间大小是相同的,知道数组的首元素的内存地址,要查找的元素只要知道下标,就可以快速的计算出偏移量,通过首元素内存地址加上偏移量,就 ...

  2. Python开发:Python运算符

    运算符 1.算数运算: 运算符 描述 实例 + 加 - 两个对象相加 a + b 输出结果 30 - 减 - 得到负数或是一个数减去另一个数 a - b 输出结果 -10 * 乘 - 两个数相乘或是返 ...

  3. Aery的UE4 C++游戏开发之旅(4)加载资源&创建对象

    目录 资源的硬引用 硬指针 FObjectFinder<T> / FClassFinder<T> 资源的软引用 FSoftObjectPaths.FStringAssetRef ...

  4. QT无法读入txt文件内容

    用vs写QT无法利用相对路径读入txt文件,应将此文件加入到资源文件中.

  5. MySQL更改默认的root账户密码

    编辑mysql的配置文件:my.ini(在MySql安装目录下). 打开配置文件,在文件最后一行添加:skip-grant-tables,然后保存退出 意思为就是在启mysql时不启动grant-ta ...

  6. k8spod的介绍

    yaml介绍 apiVersion: v1 APIserver 的版本 kind: Pod 资源类型 metadata: 元数据定义 name: pod-demo 元数据资源名字 labels: 定义 ...

  7. pycharm add configuration

    新建项目运行的时候 现实额e di t configrations

  8. Eclipse开发快捷键

    ctrl+alt+r:查找资源 ctrl+o:快速outLine ctrl+e:快速切换编辑器 ctrl+./ctrl+1:下一个错误修改

  9. 从零开始-建站前的准备之django数据库创建的问题

    稍微熟悉了一下django里面对于数据的操作,发现遇见了好多的问题. django对数据的操作是代码式的操作. 一开始在models里面开始为某个表创建参数,像username,password这样的 ...

  10. vue cli3.0打包

    1.vue cli3.0需要在项目根目录下配置webpack  包括反向代理以及打包文件路径 const webpack = require("webpack"); module. ...