GVKun编程网logo

select()如何提醒FD变为“就绪”?(select fd_set)

9

对于想了解select的读者,本文将提供新的信息,我们将详细介绍如何提醒FD变为“就绪”?,并且为您提供关于Beautifulsoup:.find()和.select()之间的区别、BufferedR

对于想了解select的读者,本文将提供新的信息,我们将详细介绍如何提醒FD变为“就绪”?,并且为您提供关于Beautifulsoup:.find()和.select()之间的区别、BufferedReader应该在什么时候不声明“就绪”、Java Collections-Map中的keyset()vs entrySet()、javascript – 如何在所有其他事件之后使jQuery“就绪”事件处理程序解雇?的有价值信息。

本文目录一览:

select()如何提醒FD变为“就绪”?(select fd_set)

select()如何提醒FD变为“就绪”?(select fd_set)

我不知道为什么我很难找到它,但是我正在看一些Linux代码,我们在其中使用select()等待文件描述符来报告它已经准备就绪。从选择的手册页中:

select() and pselect() allow a program to monitor multiple file descriptors,waiting until one or more of the file descriptors become "ready" for someclass of I/O operation

所以,那太好了……我在某个描述符上调用select,给它一些超时值,然后开始等待指示消失。文件描述符(或描述符的所有者)如何报告其“就绪”,以便select()语句返回?

答案1

小编典典

通过 返回报告已准备就绪。

select等待通常不在程序控制范围内的事件。本质上,通过调用select,您的程序会说:“直到…,我都无事可做,请暂停我的过程”。

您指定的条件是一组事件,任何事件都会唤醒您。

例如,如果您正在下载内容,则循环将不得不等待新数据到达,如果传输被卡住或用户中断,则会发生超时,而这恰恰是在select做。

当您进行多次下载时,到达任何连接的数据都会触发程序中的活动(您需要将数据写入磁盘),因此您需要select在文件描述符列表中提供所有下载连接的列表,以供注意“读”。

当您同时将数据上传到某个地方时,您将再次select用来查看连接当前是否接受数据。如果对方在拨号,则它将仅缓慢地确认数据,因此您的本地发送缓冲区始终是满的,并且任何写更多数据的尝试都将阻塞,直到缓冲区空间可用或失败为止。通过将要发送到的文件描述符select作为“写”描述符传递,一旦缓冲区空间可供发送,我们就会得到通知。

一般的想法是您的程序成为 事件驱动的
,即它对来自公共消息循环的外部事件做出反应,而不是执行顺序操作。您告诉内核“这是我要为其执行操作的一组事件”,内核为您提供了一组已发生的事件。两个事件同时发生是很常见的。例如,TCP确认包含在数据包中,这可以使相同的fd可读(数据可用)和可写(已确认的数据已从发送缓冲区中删除),因此您应该准备处理所有事件select再次致电之前。

最好的一点是,select基本上可以给您一个承诺,即一次调用readwrite不会阻塞,而无需对调用本身进行任何保证。例如,如果有一个字节的缓冲区空间可用,则可以尝试写入10个字节,内核将返回并说“我已写入1个字节”,因此您也应该准备处理这种情况。一种典型的方法是使用一个缓冲区“要写入此fd的数据”,并且只要它是非空的,就将fd添加到写入集中,并通过尝试写入所有数据来处理“
writeable”事件当前缓冲区中的数据。如果此后缓冲区为空,则可以,否则,请再次等待“可写”。

很少使用“例外”集-它用于具有带外数据的协议,在这些协议中,可能会阻止数据传输,而其他数据则需要通过。如果您的程序当前无法接受来自“可读”文件描述符的数据(例如,您正在下载并且磁盘已满),则您不想在“可读”集中包含描述符,因为您无法处理事件并select在再次调用时立即返回。如果接收方将fd包括在“例外”集中,并且发送方要求其IP堆栈发送包含“紧急”数据的数据包,则接收方将被唤醒,并可以决定丢弃未处理的数据并与发送方重新同步。的telnet协议将其用于例如Ctrl-
C处理。除非您正在设计需要这种功能的协议,否则可以轻松地将其忽略而不会造成损害。

强制代码示例:

#include <sys/types.h>#include <sys/select.h>#include <unistd.h>#include <stdbool.h>static inline int max(int lhs, int rhs) {    if(lhs > rhs)        return lhs;    else        return rhs;}void copy(int from, int to) {    char buffer[10];    int readp = 0;    int writep = 0;    bool eof = false;    for(;;) {        fd_set readfds, writefds;        FD_ZERO(&readfds);        FD_ZERO(&writefds);        int ravail, wavail;        if(readp < writep) {            ravail = writep - readp - 1;            wavail = sizeof buffer - writep;        }        else {            ravail = sizeof buffer - readp;            wavail = readp - writep;        }        if(!eof && ravail)            FD_SET(from, &readfds);        if(wavail)            FD_SET(to, &writefds);        else if(eof)            break;        int rc = select(max(from,to)+1, &readfds, &writefds, NULL, NULL);        if(rc == -1)            break;        if(FD_ISSET(from, &readfds))        {            ssize_t nread = read(from, &buffer[readp], ravail);            if(nread < 1)                eof = true;            readp = readp + nread;        }        if(FD_ISSET(to, &writefds))        {            ssize_t nwritten = write(to, &buffer[writep], wavail);            if(nwritten < 1)                break;            writep = writep + nwritten;        }        if(readp == sizeof buffer && writep != 0)            readp = 0;        if(writep == sizeof buffer)            writep = 0;    }}

我们尝试读取是否有可用的缓冲区空间,并且读取侧没有文件结尾或错误,如果缓冲区中有数据,则尝试写入。如果到达文件末尾并且缓冲区为空,那么我们就完成了。

该代码的行为显然不是最优的(它是示例代码),但是您应该能够看到内核做的比我们在读写时要求的少,这是可以接受的,在这种情况下,我们只要回头说“您已经准备就绪”,并且我们永远不会在不询问它是否会阻塞的情况下进行读写。

Beautifulsoup:.find()和.select()之间的区别

Beautifulsoup:.find()和.select()之间的区别

当您使用
BeautifulSoup

抓取网站的特定部分时,您可以使用

  • soup.find()soup.findAll()
  • soup.select()

.find().select()方法之间有区别吗?(例如,性能或灵活性等)还是相同?

BufferedReader应该在什么时候不声明“就绪”

BufferedReader应该在什么时候不声明“就绪”

我正在尝试使用 BufferedReader 通过URL上的InputStreamReader
从Web文档中读取文本(到某些Apache服务器上的文件)。

String result = "";URL url = new URL("http://someserver.domain/somefile");BufferedReader in = null;in = new BufferedReader(new InputStreamReader(url.openStream(), "iso-8859-1"));result += in.readLine();

现在,这很好。但是显然,我希望读者不要只读一行,而应该读文件中的所有行。
查看BufferedReader API,以下代码应做到这一点:

while (in.ready()) {    result += in.readLine();}

即在有更多行时读取所有行,在没有更多行时停止。但是,此代码不起作用-读者 永远不会 报告 ready()= true

我什至可以在读取一行(从文件中读取正确的字符串)之前立即打印ready()值,但阅读器将报告’ false ‘。

难道我做错了什么?当实际上有要读取的内容时,为什么BufferedReader 在就绪时返回“ false ”?

答案1

小编典典

ready()!=还有更多

ready()并不表示还有更多数据要读取。它仅显示读取 是否 会阻塞线程。在读取所有数据之前,它很可能会返回false。

要找出是否没有更多数据,请检查是否readLine()返回null

String line = in.readLine();while(line != null){   ...   line = in.readLine();}

Java Collections-Map中的keyset()vs entrySet()

Java Collections-Map中的keyset()vs entrySet()

我把一个字符串数组元素是一个映射,其中字符串数组的元素是键,单词的频率是值,例如:

String[] args = {"if","it","is","to","be","up","me","delegate"};

那么地图上将有类似 [ if:1,it:2 .... ]

Set<String> keys = m.keySet();
System.out.println("keyset of the map : "+keys);

打印所有键: "if","delegate"

Set<Map.Entry<String,Integer>> entrySet = m.entrySet();
Iterator<Map.Entry<String,Integer>> i = entrySet.iterator();
while(i.hasNext()){
    Map.Entry<String,Integer> element = i.next();
    System.out.println("Key: "+element.getKey()+",value: "+element.getValue());
}

打印所有键值对:

使用条目集将打印所有值:

Key: if,value: 1
Key: it,value: 2
Key: is,value: 2
Key: to,value: 2
Key: be,value: 1
Key: up,value: 1
Key: me,value: 1
Key: delegate,value: 1

但是下面的代码块应该输出与上面完全相同的输出,但是不会:

Iterator<String> itr2 = keys.iterator();
while(itr2.hasNext()){
    //System.out.println(itr1.next()+" ");
    //System.out.println(m.get(itr1.next())+" ");
    System.out.println("Key: "+itr2.next()+",value: "+m.get(itr2.next()));
}

它打印:

Key: if,value: 1

但是,如果我们在while循环中取消注释第1行,即

System.out.println(itr1.next()+" ");

并评论这一行

System.out.println("Key: "+itr2.next()+",value: "+m.get(itr2.next()));

然后我们得到所有键: {"if","delegate"};

如果使用m.get()with itr2.next(),则迭代器没有几个键!

javascript – 如何在所有其他事件之后使jQuery“就绪”事件处理程序解雇?

javascript – 如何在所有其他事件之后使jQuery“就绪”事件处理程序解雇?

我正在开发一个Greasemonkey脚本,它将实际升级页面上使用的jQuery版本.为此,我需要添加一个“就绪”事件处理程序,该处理程序将在页面上可能存在的所有其他事件处理器之后触发.

我知道jQuery在调用ready事件处理程序之前等待DOM可操作,那么有没有办法影响它执行它们的顺序?谢谢,

解决方法:

它们按照注册顺序调用.所以从页面顶部到底部.如果您需要将其作为最后一个已注册的就绪回调寄存器,则将其放在body标签的最后.还使用$(window).load而不是$(document).ready.

今天关于select如何提醒FD变为“就绪”?的介绍到此结束,谢谢您的阅读,有关Beautifulsoup:.find()和.select()之间的区别、BufferedReader应该在什么时候不声明“就绪”、Java Collections-Map中的keyset()vs entrySet()、javascript – 如何在所有其他事件之后使jQuery“就绪”事件处理程序解雇?等更多相关知识的信息可以在本站进行查询。

本文标签: