你怎么能使用文件描述符来刷新写入?

事实certificate,对open()和fopen()的误解源于ARM上的Linux 2.6.14内核中有错误的I2C驱动程序。 支持一个工作位的巴士司机解决了我想在这里解决的问题的根源。

我试图找出在Linux(I2C)串行设备驱动程序的问题。 看来,通过添加定时操作系统暂停(睡觉)之间的写入和读取设备的事情工作…(很多)更好。

除此之外,I2C的本质是主机读取或写入的每个字节都由线路另一端(从机)的设备确认 – 暂停的改进促使我将驱动程序视为asynchronous工作 – 这是我与巴士的工作方式无法协调。 Anyhoo …

我想要刷新写入以确保(而不是使用固定持续时间的暂停), 以某种方式testing写入/读取事务已经以multithreading友好的方式完成。

使用fflush(fd);的麻烦fflush(fd); 是它需要'fd'是stream指针(而不是文件描述符),即

 FILE * fd = fopen("filename","r+"); ... // do read and writes fflush(fd); 

我的问题是,我需要使用ioctl() ,它不使用stream指针。 即

 int fd = open("filename",O_RDWR); ioctl(fd,...); 

build议?

你有两个选择:

  1. 使用fileno()获取与stdio流指针关联的文件描述符

  2. 根本不要使用<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); 

我认为你正在寻找的可能是

 int fsync(int fd); 

要么

 int fdatasync(int fd); 

fsync会将文件从内核缓冲区刷新到磁盘。 除了元数据, fdatasync也会做。

fflush()仅刷新由stdio fopen()图层添加的缓冲区,由FILE *对象管理。 内核所看到的底层文件本身并没有被缓存在这个级别上。 这意味着使用fileno()和raw write()来绕过FILE *层的write()也不会以fflush()将会刷新的方式进行缓冲。

正如其他人所指出的, 不要混淆两者。 如果您需要使用“原始”I / O函数(如ioctl() ,则直接open()该文件, 而不使用fopen<()和来自stdio的朋友。

这听起来像你正在寻找的是fsync()函数(或fdatasync()?),或者你可以在open()调用中使用O_SYNC标志。

如果你想换一个方向(把FILE *和现有的文件描述符关联起来),使用fdopen():

  FDOPEN(P) NAME fdopen - associate a stream with a file descriptor SYNOPSIS #include <stdio.h> FILE *fdopen(int fildes, const char *mode); 

你有没有尝试禁用缓冲?

 setvbuf(fd, NULL, _IONBF, 0);