Прерывание Выберите, чтобы добавить еще один сокет для просмотра в Python. - PullRequest
2 голосов
/ 11 января 2011

Я реализую одноранговый IPC с использованием TCP в приложении Windows XP.

Я использую модули select и socket в Python 2.6.6.

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

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

Под winsock Я могу позвонить WSACancelBlockingCall, что изящно прервет выбор.

Таким образом, мой вопрос таков: возможно ли сделать все это питонским способом, не прибегая к использованию poll()?

Многие, спасибо

- DM

Ответы [ 2 ]

5 голосов
/ 11 января 2011

Вы можете попробовать добавить в свой набор дополнительный файловый дескриптор, который вы используете в качестве механизма сигнализации.Затем вы можете написать в этот дескриптор фиктивное значение, чтобы вызвать select для выхода.Например:

my_pipe = os.pipe()
...
while True:
    ready_fds = select.select(my_read_fds + [my_pipe[0]],
                              my_write_fds, my_except_fds, timeout)
    if my_pipe[0] in ready_fds[0]:
        # Add another fd to my_read_fds, etc.
        os.read(my_pipe[0], 1)
    ...

# To interrupt the current select call and add a new fd, write to the pipe:
os.write(my_pipe[1], 'x')
1 голос
/ 05 марта 2011

Я не могу добавлять комментарии, поэтому я добавляю это как ответ.

Не используйте WSACancelBlockingCall.Вы должны использовать подход из ответа Адама Розенфилда .Просто создайте пару фиктивных сокетов, соединенных друг с другом, вместо фиктивного дескриптора файла.Включите один из этих сокетов в ваш select() звонок.Когда вам нужно прервать вызов - просто запишите байт во второй фиктивный сокет.

О, и не забудьте прочитать этот байт из первого сокета, когда вернется select().

...