如何使用文件描述符刷新写入?
- 2024-11-01 08:41:00
- admin 原创
- 36
问题描述:
事实证明,对 open() 与 fopen() 的整个误解源于 ARM 上的 Linux 2.6.14 内核中存在错误的 I2C 驱动程序。反向移植一个有效的 bit bash 驱动程序解决了我试图在此解决的问题的根本原因。
我正在尝试解决 Linux (I2C) 中串行设备驱动程序的问题。看来,通过在设备上的写入和读取之间添加定时操作系统暂停(休眠),事情会变得更好。
另外:I2C 的本质是主机读取或写入的每个字节都会被线路另一端的设备(从机)确认 - 暂停改善了事情,促使我认为驱动程序是异步工作的 - 这与总线的工作方式不符。无论如何...
我要么想刷新写入以确保(而不是使用固定持续时间的暂停),要么以某种方式测试写入/读取事务是否已以多线程友好的方式 完成。
使用的问题fflush(fd);
在于它要求“fd”是流指针(而不是文件描述符),即
FILE * fd = fopen("filename","r+");
... // do read and writes
fflush(fd);
我的问题是我需要使用ioctl()
,它不使用流指针。即
int fd = open("filename",O_RDWR);
ioctl(fd,...);
有什么建议吗?
解决方案 1:
我认为你正在寻找的可能是
int fsync(int fd);
或者
int fdatasync(int fd);
fsync
将把文件从内核缓冲区刷新到磁盘。fdatasync
除了元数据之外还会执行其他操作。
解决方案 2:
您有两个选择:
用于获取与流指针
fileno()
关联的文件描述符stdio
根本不要使用
<stdio.h>
,这样您也不需要担心刷新 - 所有写入都会立即发送到设备,并且对于字符设备,调用write()
甚至不会返回,直到较低级别的 IO 完成(理论上)。
对于设备级 IO,我认为使用 非常不常见stdio
。我强烈建议使用较低级别的open()
、read()
和write()
函数(基于您后来的回复):
int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);
解决方案 3:
fflush()
仅刷新由 stdio 层添加的缓冲fopen()
,由FILE *
对象管理。内核所见的底层文件本身并未在此级别进行缓冲。这意味着绕过该FILE *
层的写入(使用fileno()
和 raw )也不会以刷新的write()
方式进行缓冲。fflush()
正如其他人指出的那样,尽量不要将两者混用。如果您需要使用诸如 之类的“原始” I/O 函数ioctl()
,则open()
直接使用 file ,而无需使用fopen<()
stdio 中的 和 friends。
解决方案 4:
您是否尝试过禁用缓冲?
setvbuf(fd, NULL, _IONBF, 0);
解决方案 5:
听起来您正在寻找的是 fsync() 函数(或 fdatasync()?),或者您可以在 open() 调用中使用 O_SYNC 标志。
解决方案 6:
如果您想反过来(将 FILE* 与现有的文件描述符关联),请使用 fdopen() :
FDOPEN(P)
NAME
fdopen - associate a stream with a file descriptor
SYNOPSIS
#include <stdio.h>
FILE *fdopen(int fildes, const char *mode);
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件