Управление дескрипторами файлов для select.select в Python - PullRequest
4 голосов
/ 18 октября 2010

У меня есть проблема с зудом, которую, я знаю, можно решить разными способами, но я все же хотел бы знать, возможен ли следующий подход в Python.

Предположим, у меня есть сокет, которого я постоянно ждувход, и есть некоторое условие, которое в конечном итоге завершает всю программу.Я хочу сделать это способом BLOCKING, как я себе представлял, используя select.select:

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

Теперь, если есть некоторый дескриптор файла fd, который я могу вручную установить в состояние готовности, либо прочитайтеили написать, я могу сделать

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

Конечно, я могу просто отправить сообщение в mysocket, вызывая его разблокировку, но я все равно хотел бы знать, есть ли программный способ манипулировать дескриптором файла длясостояние готовности.

РЕДАКТИРОВАТЬ: Мой вопрос: могу ли я как-то установить дескриптор файла на «готово» вручную?

Спасибо всем.

Ответы [ 3 ]

2 голосов
/ 21 октября 2010

Самое простое, что можно сделать, это, вероятно, использовать os.mkfifo() для создания пары файлов, добавить конец чтения к вызову select(), а затем записать в конец записи, когда вы хотите разблокировать.

Также вы можете рассмотреть возможность добавления таймаута к вызову select();Я не могу себе представить, что вы будете делать достаточно в течение разблокированного времени, чтобы снизить производительность.

0 голосов
/ 04 мая 2013

Использование безымянного канала os.pipe () также будет хорошо работать здесь (блокировка на конце чтения, запись на конец записи) и избавит вас от необходимости указывать путь.

Я нашел такой вид установки полезным для нескольких потоков, когда я хочу, чтобы один поток мог прервать блокировку другого потока при вызове select.

0 голосов
/ 21 октября 2010

Я думаю, что вам нужно будет создать пару сокетов (см. Функцию socket.socketpair()) и создать отдельный поток Python (используйте класс threading.Thread), чтобы следить за специальным условием, сообщающим вашей программе, когда завершать работу.Когда поток обнаруживает условие, он может написать «Готово!»(или что-то еще) на своем конце пары сокетов.Если у вас есть другой конец пары сокетов в списке сокетов, которые вы ожидаете для чтения, он загорится и скажет, что он доступен для чтения, как только "Готово!"появляется и готов к считыванию из сокета.

...