简体   繁体   English

在Python中操作select.select的文件描述符

[英]Manipulate File Descriptors for select.select in Python

I have an itching problem I know could be solved using many different ways, but I would still like to know if the following approach is possible in Python. 我有一个瘙痒的问题,我知道可以使用许多不同的方法解决,但我仍然想知道在Python中是否可以使用以下方法。

Suppose I have some socket I am constantly waiting for input on, and there is some condition that eventually terminates the whole program. 假设我有一些套接字,我一直在等待输入,并且某些情况最终会终止整个程序。 I want to do it in a BLOCKING fashion, as I imagined, using select.select: 我想像我想象的那样,使用select.select以阻塞的方式进行操作:

readfds, writefds, errfds = select.select([mysocket],[],[])
if readfds:
    conn, addr = mysocket.accept()
    ...

Now, if there is some file descriptor fd, that I can manually set to a ready condition, either read or write, I can do 现在,如果有一些文件描述符fd,我可以手动将其设置为就绪状态,无论是读取还是写入,我都可以

readfds, writefds, errfds = select.select([mysocket,fd],[],[])
for r in readfds:
    if r == mysocket:
        conn, addr = mysocket.accept()
        ...
    else:
        <terminate>

Of course, I can simply send a message to mysocket, causing it to unblock but I would still like to know if there is a programmatic way to manipulate a file descriptor to a ready state. 当然,我可以简单地将一条消息发送到mysocket,使其解除阻止,但我仍然想知道是否存在以编程方式将文件描述符操纵为就绪状态。

EDIT: My question is: can I somehow set a file descriptor to "ready" manually? 编辑:我的问题是:我可以以某种方式手动将文件描述符设置为“就绪”吗?

Thanks all. 谢谢大家

The easiest thing to do is probably to use os.mkfifo() to create a file pair, add the read end to the select() call, and then write to the write end when you want to unblock. 最简单的操作可能是使用os.mkfifo()创建一个文件对,将read end添加到select()调用中,然后在要取消阻止时写入write端。

Also, you might want to consider just adding a timeout to the select() call; 另外,您可能需要考虑将超时添加到select()调用中; I can't imagine that you'd be doing enough during the unblocked time to drag performance down. 我无法想象您会在畅通无阻的时间内完成足够的工作以降低性能。

Using an unnamed pipe os.pipe() would also work well here (block on the read end, write to the write end) and keep you from having to specify a path. 使用未命名的管道os.pipe()在这里也可以很好地工作(在读取端阻塞,写入到写入端),并使您不必指定路径。

I've found this sort of setup useful with multiple threads, when I want one thread to be able to interrupt another thread's blocking on a select call. 当我希望一个线程能够在select调用中中断另一个线程的阻塞时,我发现这种设置对多个线程很有用。

I think that you will have to create a socket pair (see the socket.socketpair() function) and spawn a separate Python thread (use the threading.Thread class) to watch for the special condition that tells your program when to end. 我认为您将必须创建一个套接字对(请参阅socket.socketpair()函数)并生成一个单独的Python线程(使用threading.Thread类)来监视可告知程序何时结束的特殊条件。 When the thread detects the condition, it can write "Done!" 当线程检测到条件时,可以写“ Done!”(完成!)。 (or whatever) on to its end of the socket pair. (或其他)插入套接字对的一端。 If you have the other end of the socket pair in the list of sockets you are waiting on for reading, then it will light up and say that it is readable as soon as the "Done!" 如果您要等待的套接字列表中有该对套接字的另一端,则该套接字将亮起并说“完成!”是可读的。 appears and is ready to be read off of the socket. 出现并准备从插座中读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM