вырваться из гнезда выбора - PullRequest
8 голосов
/ 21 марта 2010

У меня есть цикл, который в основном вызывает это каждые несколько секунд (после тайм-аута):

 while(true){

    if(finished)
       return;

    switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)){
        case SOCKET_ERROR : report bad stuff etc; return;
        default : break;
    }

    // do stuff with the incoming connection
 }

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

Это выполняется в потоке B (не в основном потоке). Бывают моменты, когда я хочу немедленно завершить этот цикл принятия из потока A (основного потока), но мне кажется, что мне нужно ждать, пока временной интервал не закончится ..

Есть ли способ прервать функцию выбора из другого потока, чтобы поток B мог выйти немедленно?

Ответы [ 4 ]

11 голосов
/ 21 марта 2010

Самый простой способ - использовать pipe(2) для создания канала и добавить конец чтения к readfds. Когда другой поток хочет прервать select(), просто запишите в него байт, а затем используйте его.

3 голосов
/ 21 марта 2010

Да, вы создаете подключенную пару сокетов. Затем поток B записывает данные в одну сторону сокета, а поток A добавляет сокет другой стороны для выбора. Поэтому, как только B записывает в сокет A выход из select, не забудьте прочитать этот байт из сокета.

Это самый стандартный и распространенный способ прерывания выбора.

Примечания:

В Unix используйте socketpair для создания пары сокетов, в Windows это немного сложно, но поиск в Google для Windows socketpair даст вам примеры кода.

0 голосов
/ 08 апреля 2016

Вы можете использовать вызов shutdown (Sock, SHUT_RDWR) из основного потока, чтобы выйти из ожидающего вызова select, который также выйдет из вашего другого потока до истечения времени ожидания, поэтому вам не нужно ждать до истечения времени ожидания.

веселит. :)

0 голосов
/ 21 марта 2010

Разве вы не можете просто сделать тайм-аут достаточно коротким (например, 10 мс или около того?).

Эти решения типа "просто создайте фиктивное соединение" кажутся взломанными. Я лично считаю, что если приложение хорошо спроектировано, параллельные задачи никогда не нужно принудительно прерывать, достаточно просто проверять работника (это также причина, по которой в boost.threads нет функции завершения).

Редактировать Сделал этот ответ CV. Это плохо, но это может помочь другим понять, почему это плохо, что объясняется в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...