gpt4 book ai didi

c - select() 返回无效参数

转载 作者:太空狗 更新时间:2023-10-29 14:52:53 28 4
gpt4 key购买 nike

我成功地从另一个线程的管道中读取数据,并打印输出(恰好在 ncurses 窗口中)。

出于各种原因,我需要一次执行一个字符,并且我在 FD 上使用 select() 作为管道的读取端,以及一些其他 FD(如标准输入)。

我的想法是仅在管道即将被读取时才尝试从管道读取,而不是处理任何输入。这似乎在起作用——至少开始了。 select() 设置 fd_set,如果是 FD_ISSET,我会从 FD 读取 1 个字节。但是 select() 说是一次太多了,read() 阻塞了。

所以我的问题是 - 为什么 select() 会报告 fd 已准备好读取,如果后续的 read() 阻塞?

(大约)当管道的另一端连接到一个 fork 进程时,同样的代码可以正常工作,如果有帮助的话。

我可以根据要求发布代码,但它是沼泽标准。设置一个 fd_set,复制它,选择副本,如果设置了 FD,则调用一个从同一 FD 读取字节的函数...否则恢复 fd_set 副本

编辑:应要求,代码如下:

设置我的 fd_set:

fd_set fds;
FD_ZERO(&fds);
FD_SET(interp_output[0], &fds);
FD_SET(STDIN_FILENO, &fds);
struct timeval timeout, tvcopy; timeout.tv_sec=1;
int maxfd=interp_output[0]+1; //always >stdin+1
fd_set read_fds;
FD_COPY(&fds, &read_fds);

在循环中:

if (select(maxfd, &read_fds, NULL, NULL, &timeout)==-1) {perror("couldn't select"); return;}
if (FD_ISSET(interp_output[0], &read_fds)) {
handle_interp_out();
} else if (FD_ISSET(STDIN_FILENO, &read_fds)) {
//waddstr(cmdwin, "stdin!"); wrefresh(cmdwin);
handle_input();
}

FDCOPY(&fds, &read_fds);

handle_interp_out():

void handle_interp_out() {
int ch;
read(interp_output[0], &ch, 1);
if (ch>0) {
if (ch=='\n') { if (cmd_curline>=cmdheight) cmdscroll(); wmove(cmdwin, ++cmd_curline, 1); }
else waddch(cmdwin, ch);
wrefresh(cmdwin);
}
}

编辑 2:写入代码只是用 fdopen(interp_output[1], "w") 打开的 FILE* 上的 fprintf - 这是在不同的线程中。我所要做的只是我的“提示>”——它正确地打印了所有内容,但又进行了一次它不应该进行的迭代。我关闭了缓冲,这给我带来了其他问题。

编辑 3:这已成为我调用 select() 的问题。看起来,它立即返回 -1 并且 errno 被设置为“无效参数”。 read() 不知道这一点,只是继续前进。我的 select() 有什么问题?我更新了代码并更改了标题以更准确地反射(reflect)问题...

编辑 4:所以现在我完全糊涂了。不知何故,.tv_sec=1 的超时值不好。通过摆脱它,代码工作得很好。如果有人有任何理论,我洗耳恭听。我会将其保留为 NULL,除非该线程需要定期进行更新。

最佳答案

为了绝对保证读取永远不会阻塞,您必须在 fd 上设置 O_NONBLOCK。

您的选择错误几乎可以肯定是因为您没有设置整个时间结构。你只是在设置秒数。另一个字段将包含从堆栈中拾取的垃圾数据。

使用结构初始化。这将保证其他字段设置为 0。

看起来像这样:

struct timeval timeout = {1, 0};

此外,在您的选择循环中,您应该知道 Linux 会将剩余时间写入超时值。这意味着下一次循环不会为 1 秒,除非您将该值重置为 1 秒。

关于c - select() 返回无效参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4364474/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com