повреждение из выбора сокета

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

 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 (не основной поток). Существуют времена, когда я хочу закончить этот акцепторный цикл сразу от потока (основной поток), но кажется, что я должен ожидать, пока временной интервал не заканчивается..

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

9
задан kamziro 21 March 2010 в 00:37
поделиться

3 ответа

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

11
ответ дан 3 November 2019 в 00:00
поделиться

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

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

Примечания:

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

3
ответ дан 3 November 2019 в 00:00
поделиться

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

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

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

-1
ответ дан 3 November 2019 в 00:00
поделиться