unix环境高级编程之unbuffered io

 

五个文件io函数,open,read,write,lseek,close;

不带缓冲的io是指每个read,write函数都调用内核中的一个系统调用。它在多进程间共享资源,原子操作就变得很重要。

 

文件描述符:

对于内核而言,所有打开的文件都是通过文件描述符引用。他是一个费负整数,当打开或者创建一个文件,内核向进程返回一个文件描述符。

当读或者写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传给read或write。

0----标准输入  STDIN_FILENO

1-----标准输出 STDOUT_FILENO

2-----标准错误输出 STDERR_FILENO (定义在unistd.h中)

 

文件描述符限制在0-OPEN_MAX间

 

open函数

#include<fcntl.h>

int open(const char *pathname, int flag, /* mod_t mode */)

成功返回文件描述符,失败返回-1

flag有以下几种,可以用或运算构成flag参数

O_RDONLY 只读 0 

O_WRONLY  只写 1 

O_RDWR  读写 2

 

这三个常量中必须指定一个且只能指定一个,则下列常量是可选的。

O_APPEND 每次写追加到末尾

O_CREAT 若此文件不存在则创建它,使用此选项时需要指定第三个参数设置文件的访问权限

O_EXCL 如果同时指定了O_CREAT,而文件存在,则会报错。可用来测试一个文件是否存在,如果不存在则创建之,使测试和创建成为一个原子操作。
O_TRUNC 如果此文件存在,而且为只写或读写成功打开,则将长度截短为0
O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。
O_NOBLOCK 如果pahtname指的是一个FIFO,一个特殊块,或一个字符特殊文件,则此选项为文件的本次打开操作和后续的io操作设置非阻塞模式.
下面这三个操作是可选的
O_DSYNC 使每次write等待物理io操作完成,但是如果写操作并不影响读取到刚写入的数据,则不等待文件属性被更新。
O_RSYNC 使每一个以文件描述符作为参数的read操作等待,直到任何对文件同一部分进行的未决写操作都完成
O_SYNC 使每次写都等到物理io完成,包括有write操作引起的文件属性更新所需要的io。
creat函数
#include<fcntl.h>
int creat(const char *pathname, mod_t mod)
若成功则返回只写打开的文件描述符,否则返回-1
等价于
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mod)
由于unix早期版本中,open函数第二个参数只能是0,1或2,没有办法打开一个不存在的文件,因此需要creat创建一个新文件,现在open提供了O_CREAT, O_TRUNC,于是也不需要creat函数
close 函数
关闭一个打开的文件
#include <unistd.h>
int  close(int filedes)
成功返回0,失败返回-1
lseek函数
没打开一个文件都会有一个与其相关联的“当前文件偏移量”,通常是一个非负整数,读写都是从当前文件偏移量开始,并使偏移量增加所读写的字节数。打开一个文件如果没有指定O_APPEND,则默认偏移量为0,这也是为什么写会覆盖原先的数据。
#include<unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
成功返回新的文件偏移量,失败返回-1
对offset的解释与参数whence有关
若whence是SEEK_SET,则将偏移量设置为据文件开始处offset字节。
若whence是SEEK_CUR,  则将偏移量设置为据当前值加上offset,offset可为正或负。
若whence是SEEK_END, 则将文件偏移量设置为文件长度加offset,offset可正可负。
若lseek成功则放回新的文件偏移量,失败返回-1
可用lseek(filedes, 0, SEEK_CUR)来测试文件是否可以设置偏移量。如果文件描述符引用的是FIFO,网络套接字,管道,则lseek返回-1,并将errno设置为ESPIPE
lseek便宜了记录在内核中,并不引起io操作,然后该偏移量用于下一个读或写操作。
偏移量大于当前文件长度将会引起文件空洞,文件空洞并不需要占用存储空间。
read函数
#include<unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
若成功则返回读到的字节数,读到文件尾则返回0,错误返回 -1
write函数
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
返回值与nbytes相同,否则表示出错。通常是磁盘已满,或者是超过一个给定进程的文件长度。
I/O效率

当bufsize为1024时io效率最好,可由试验得到。

 

文件共享

unix支持在不同的进程间共享打开的文件。

内核使用三种数据结构表示打开的文件。

1。每个进程在进程表中都有一个记录项。

2。内核为打开的所有文件维护一张文件表。

3。每个打开文件或设备都有一个v节点结构。

 

原子性操作

pread,pwrite

 

dup和dup2函数

用来复制一个现存的文件描述符

dup(filedes);等效于 fcntl(filedes, F_DUPFD, 0);

而调用dup2(filedes, filedes2)等效于close(filedes2); fcntl(filedes, FDUPFD, filedes2);

后一种情况并不完全等于close加上fcntl操作,因为dup2是原子操作

 

sync,fsync,fdatasync函数

传统unix实现在内核中并没有高速缓冲去,高速缓存,或页面高速缓存,大多数io都是通过缓冲进行。

#include<unistd.h>

int fsync(int filedes);

int fdatasync(int filedes);

成功返回0, 错误返回-1

void sync(void);

sync 只将所有修改过的块缓冲区排入写入队列,然后就返回,并不等待实际写磁盘操作结束。

通常称为update的系统守护程序会周期性的调用sync函数。这就定期的冲洗内核的块缓冲区。

 

fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束。可用于数据库类的程序,可以保证修改过的块立即写入到磁盘上。

fdatasync类似于fsync,但它只影响文件的数据部分。而数据外,fsync还会更新文件的属性。

 

fcntl函数

改变已经打开文件的性质。

#include <fcntl.h>

int fcntl(int filedes, int cmd, .../* int arg */);

返回值:若成功则依赖于cmd,出错返回-1

fcntl函数有五种功能:

1。复制一个现有的描述符 cmd=F_DUPFD

2。获得/设置文件描述符标记 cmd=F_GETFD/F_SETFD

3。获得设置文件状态标志 cmd=F_GETFL/F_SETFL

4。获得设置异步io所有权 cmd=F_GETOWN/F_SETOWN

5。获得/设置记录锁 cmd=F_GETLK, F_SETLK或者F_SETLKW

 

ioctl函数

ioctl函数是io操作的杂物箱,不能用本章中的其他函数表示的io函数都能用ioctl表示。

终端io是ioctl的最大 使用方面

#include <unistd.h>

#include <sys/ioctl.h>

#include <stropts.h>

int ioctl(int filedes,  int request, ...);

出错返回-1,成功返回其他值。

 

/dev/fd

较新的系统度提供了/dev/fd目录,其目录项是名为0,1,2等文件,打开/dev/fd/n等效于复制描述符n,(假定描述符n是打开的);

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于PyTorch的Embedding和LSTM的自动写诗实验LSTM (Long Short-Term Memory) 是一种特殊的循环神经网络(RNN)架构,用于处理具有长期依赖关系的序列数据。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致无法有效地捕捉长期依赖。LSTM通过引入门控机制(Gating Mechanism)和记忆单元(Memory Cell)来克服这些问题。 以下是LSTM的基本结构和主要组件: 记忆单元(Memory Cell):记忆单元是LSTM的核心,用于存储长期信息。它像一个传送带一样,在整个链上运行,只有一些小的线性交互。信息很容易地在其上保持不变。 输入门(Input Gate):输入门决定了哪些新的信息会被加入到记忆单元中。它由当前时刻的输入和上一时刻的隐藏状态共同决定。 遗忘门(Forget Gate):遗忘门决定了哪些信息会从记忆单元中被丢弃或遗忘。它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 输出门(Output Gate):输出门决定了哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。同样地,它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 LSTM的计算过程可以大致描述为: 通过遗忘门决定从记忆单元中丢弃哪些信息。 通过输入门决定哪些新的信息会被加入到记忆单元中。 更新记忆单元的状态。 通过输出门决定哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。 由于LSTM能够有效地处理长期依赖关系,它在许多序列建模任务中都取得了很好的效果,如语音识别、文本生成、机器翻译、时序预测等。
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的这个代码主要是研究手写数字的识别效率,用卷积神经网络算法来实现,用的是官方手写字体数据,能够显现百分之九十以上的识别率+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值