为什么在进程退出时数据不会被刷新到文件?

int main(int argc, char *argv[]) { FILE *fp = fopen("a.txt", "wt"); fprintf(fp, "AAAA"); // No flush. and No close raise(SIGTERM); exit(EXIT_SUCCESS); } 

result: No data has written to a.txt

我预料这很好。 因为系统将closures文件句柄,然后文件系统驱动程序在其Close处理程序中刷新未刷新的数据。 但事实并非如此。 我在EXT4上testing了这个代码,ubuntu 11.10

问题:我认为所有文件系统都必须在他的密切处理中刷新未刷新的数据。
Posix没有规则?

PS这个代码在NTFS,Win7上运行的很好(刷新的很好)

 int _tmain(int argc, _TCHAR* argv[]) { HANDLE h = CreateFile(L"D:\\a.txt", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0); BYTE a[3]; memset(a, 'A', 3); DWORD dw; WriteFile(h, (PVOID)a, 3, &dw, 0); TerminateProcess(GetCurrentProcess(), 1); return 0; } 

编辑:
我用系统调用write再次testing它。 它被冲洗得很好。

 int main(int argc, char** argv) { int fd = open("a.txt", O_CREAT|O_TRUNC|O_WRONLY); char buf[3]; memset(buf, 'A', 3); size_t result = write(fd, buf, 3); raise(SIGTERM); exit(EXIT_SUCCESS); return 0; } 

它与文件系统驱动程序没有任何关系。 问题是CRT正在缓冲文件流本身。 你用setvbuf()设置缓冲区大小,如果你不使用这个函数,它使用默认值。 当使用WriteFile()时,应用程序中没有缓冲区,输出缓冲在操作系统的文件系统缓存中。 免于突然的应用程序中止。

你将不得不调用fflush()来达到同样的效果。

这与文件系统无关,而是您正在使用的C实现的行为决定何时打开流。

在POSIX下, SIGTERM信号的默认动作是:

过程异常终止。 这个过程终止了_exit()的所有后果…

_exit()等同于根据C标准的_Exit() ,并且标准没有指定是否刷新流的选择:

_Exit()和_exit()函数不应该调用使用atexit()注册的函数,也不要调用任何注册的信号处理程序。 无论是打开或关闭流,或临时文件被删除是实施定义…

假设你在Linux上使用glibc,从文档 (重点是我的):

当一个进程由于某种原因而终止时(或者是程序终止,或者是一个信号的结果),就会发生下面的事情:

  • 该进程中所有打开的文件描述符都被关闭。 请参阅低级I / O。 请注意,流程终止时不会自动刷新流 ; 请参阅Streams上的I / O。

我不熟悉Windows的WriteFileTerminateProcess所以我不能评论记录的行为是什么。