我一直在阅读有关EINTR对write(2)等,并试图确定是否我需要在我的程序进行检查.作为一个完整性检查,我试图写一个会遇到它的程序.程序永远循环,重复写入文件.
然后,在一个单独的shell中,我运行:
while true; do pkill -HUP test; done
Run Code Online (Sandbox Code Playgroud)
但是,我从test.c看到的唯一输出是.来自信号处理程序的s.为什么SIGHUP导致write(2)失败?
test.c的:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
void hup_handler(int sig)
{
printf(".");
fflush(stdout);
}
int main()
{
struct sigaction act;
act.sa_handler = hup_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGHUP, &act, NULL);
int fd = open("testfile", O_WRONLY);
char* buf = malloc(1024*1024*128);
for (;;)
{
if (lseek(fd, 0, SEEK_SET) == -1)
{
printf("lseek failed: %s\n", strerror(errno));
}
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
{
printf("write failed: %s\n", strerror(errno));
}
}
}
Run Code Online (Sandbox Code Playgroud)
Linux往往会避免EINTR写入/读取文件; 看这里的讨论.虽然进程在磁盘写入时阻塞,但它可能处于不间断睡眠状态(进程代码D),表示当时不能中断.这取决于设备驱动程序; Linux设备驱动程序的在线副本,第3版是从内核方面看出它的一个很好的参考.
您仍然需要为可能不相同的其他平台处理EINTR,或者对于绝对可能发生EINTR的管道和插槽.
请注意,您一次只写sizeof(void *)字节:
char* buf = malloc(1024*1024*128);
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
Run Code Online (Sandbox Code Playgroud)
这应该是
const size_t BUF_SIZE = 1024*1024*128;
char* buf = malloc(BUF_SIZE);
if (write(fd, buf, BUF_SIZE) != BUF_SIZE)
Run Code Online (Sandbox Code Playgroud)
有两种可能性:
你写的字节很少,因为你误用了sizeof算子.因此,write瞬间发生并且它永远不会被打断 - 你一次只能写4或8个字节
不知何故,系统调用重新启动,就像你申请SA_RESTART了一样sigaction
在你的代码中,因为buf是一个指针,sizeof(buf)产生机器上指针的大小,而不是(更大)分配的空间
| 归档时间: |
|
| 查看次数: |
3126 次 |
| 最近记录: |