- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我成功地从另一个线程的管道中读取数据,并打印输出(恰好在 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/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在编码时,我问了自己这个问题: 这样更快吗: if(false) return true; else return false; 比这个? if(false) return true; return
如何在逻辑条件下进行“返回”? 在这样的情况下这会很有用 checkConfig() || return false; var iNeedThis=doSomething() || return fa
这是我的正则表达式 demo 如问题所述: 如果第一个数字是 1 则返回 1 但如果是 145 则返回 145 但如果是 133 则返回 133 样本数据a: K'8134567 K'81345678
在代码高尔夫问答部分查看谜题和答案时,我遇到了 this solution返回 1 的最长和最晦涩的方法 引用答案, int foo(void) { return! 0; } int bar(
我想在下面返回 JSON。 { "name": "jackie" } postman 给我错误。说明 Unexpected 'n' 这里是 Spring Boot 的新手。 1日龄。有没有正确的方法来
只要“is”返回 True,“==”不应该返回 True 吗? In [101]: np.NAN is np.nan is np.NaN Out[101]: True In [102]: np.NAN
我需要获取所有在 6 号或 7 号房间或根本不在任何房间的学生的详细信息。如果他们在其他房间,简单地说,我不希望有那个记录。 我的架构是: students(roll_no, name,class,.
我有一个表单,我将它发送到 php 以通过 ajax 插入到 mysql 数据库中。一切顺利,php 返回 "true" 值,但在 ajax 中它显示 false 消息。 在这里你可以查看php代码:
我在 Kotlin 中遇到了一个非常奇怪的无法解释的值比较问题,以下代码打印 假 data class Foo ( val a: Byte ) fun main() { val NUM
请注意,这并非特定于 Protractor。问题在于 Angular 2 的内置 Testability service Protractor 碰巧使用。 Protractor 调用 Testabil
在调试窗口中,以下表达式均返回 1。 Application.WorksheetFunction.CountA(Cells(4 + (i - 1) * rows_per_record, 28) & "
我在本地使用 jsonplaceholder ( http://jsonplaceholder.typicode.com/)。我正在通过 extjs rest 代理测试我的 GET 和 POST 调用
这是 Postman 为成功调用我的页面而提供的(修改后的)代码段。 var client = new RestClient("http://sub.example.com/wp-json/wp/v2
这个问题在这里已经有了答案: What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must
我想我对 C 命令行参数有点生疏。我查看了我的一些旧代码,但无论这个版本是什么,都会出现段错误。 运行方式是 ./foo -n num(其中 num 是用户在命令行中输入的数字) 但不知何故它不起作用
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile() 返回 INVALID_HANDLE_VALUE,并且 GetLastErro
即使 is_writable() 返回 true,我也无法写入文件。当然,该文件存在并且显然是可读的。这是代码: $file = "data"; echo file_get_contents($fil
下面代码中的变量 $response 为 NULL,尽管它应该是 SOAP 请求的值。 (潮汐列表)。当我调用 $client->__getLastResponse() 时,我从 SOAP 服务获得了
我一直在网上的不同论坛上搜索答案,但似乎没有与我的情况相符的... 我正在使用 Windows 7,VS2010。 我有一个使用定时器来调用任务栏刷新功能的应用程序。在该任务栏函数中包含对 LoadI
我是一名优秀的程序员,十分优秀!