Linux 如何使用文件描述符刷新写入?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/259355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:41:25  来源:igfitidea点击:

How can you flush a write using a file descriptor?

clinuxstdioi2c

提问by Jamie

It turns out this whole misunderstanding of the open() versus fopen() stems from a buggy I2C driver in the Linux 2.6.14 kernel on an ARM. Backporting a working bit bashed driver solved the root cause of the problem I was trying to address here.

事实证明,对 open() 与 fopen() 的整个误解源于 ARM 上 Linux 2.6.14 内核中存在缺陷的 I2C 驱动程序。向后移植一个工作位 bashed 驱动程序解决了我试图在这里解决的问题的根本原因。

I'm trying to figure out an issue with a serial device driver in Linux (I2C). It appears that by adding timed OS pauses (sleeps) between writes and reads on the device things work ... (much) better.

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

Aside: The nature of I2C is that each byte read or written by the master is acknowledged by the device on the other end of the wire (slave) - the pauses improving things encourage me to think of the driver as working asynchronously - something that I can't reconcile with how the bus works. Anyhoo ...

旁白:I2C 的本质是主机读取或写入的每个字节都由线路另一端的设备(从机)确认 - 改进的暂停鼓励我将驱动程序视为异步工作 - 我无法与公共汽车的工作方式相协调。随便...

I'd either like to flushthe write to be sure (rather than using fixed duration pause), orsomehow test that the write/read transaction has completedin an multi-threaded friendly way.

我想无论是喜欢刷新写可以肯定(而不是使用固定的工期暂停),以某种方式测试写/读事务已完成在多线程友好的方式。

The trouble with using fflush(fd);is that it requires 'fd' to be stream pointer (not a file descriptor) i.e.

使用的麻烦fflush(fd);在于它需要“fd”是流指针(不是文件描述符)即

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

My problem is that I require the use of the ioctl(), which doesn't use a stream pointer. i.e.

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

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

Suggestions?

建议?

采纳答案by Alnitak

You have two choices:

你有两个选择:

  1. Use fileno()to obtain the file descriptor associated with the stdiostream pointer

  2. Don't use <stdio.h>at all, that way you don't need to worry about flush either - all writes will go to the device immediately, and for character devices the write()call won't even return until the lower-level IO has completed (in theory).

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

  2. 根本不要使用<stdio.h>,这样你也不需要担心刷新 - 所有写入都会立即进入设备,对于字符设备,write()调用甚至不会返回,直到低级 IO 完成(在理论)。

For device-level IO I'd say it's pretty unusual to use stdio. I'd strongly recommend using the lower-level open(), read()and write()functions instead (based on your later reply):

对于设备级 IO,我会说使用stdio. 我强烈建议使用较低级别的open(),read()write()函数(根据您稍后的回复):

int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);

回答by unwind

fflush()only flushes the buffering added by the stdio fopen()layer, as managed by the FILE *object. The underlying file itself, as seen by the kernel, is not buffered at this level. This means that writes that bypass the FILE *layer, using fileno()and a raw write(), are also not buffered in a way that fflush()would flush.

fflush()仅刷新fopen()FILE *对象管理的 stdio层添加的缓冲。内核看到的底层文件本身不在此级别进行缓冲。这意味着绕过FILE *层的写入,使用fileno()和原始write(),也不会以fflush()刷新的方式缓冲。

As others have pointed out, try notmixing the two. If you need to use "raw" I/O functions such as ioctl(), then open()the file yourself directly, withoutusing fopen<()and friends from stdio.

正如其他人指出的那样,尽量不要将两者混合。如果您需要使用“原始”I/O 函数,例如ioctl(),则open()直接使用自己的文件,而无需使用fopen<()来自 stdio 的朋友。

回答by unwind

If you want to go the other way round (associate FILE* with existing file descriptor), use fdopen() :

如果您想反过来(将 FILE* 与现有文件描述符相关联),请使用 fdopen() :

                                                          FDOPEN(P)

NAME

       fdopen - associate a stream with a file descriptor

SYNOPSIS

       #include <stdio.h>

       FILE *fdopen(int fildes, const char *mode);

回答by jstedfast

It sounds like what you are looking for is the fsync() function (or fdatasync()?), or you could use the O_SYNC flag in your open() call.

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

回答by Danke Xie

I think what you are looking for may be

我想你正在寻找的可能是

int fsync(int fd);

or

或者

int fdatasync(int fd);

fsyncwill flush the file from kernel buffer to the disk. fdatasyncwill also do except for the meta data.

fsync将文件从内核缓冲区刷新到磁盘。fdatasync除了元数据之外也可以。

回答by rustyx

Have you tried disabling buffering?

您是否尝试过禁用缓冲?

setvbuf(fd, NULL, _IONBF, 0);