Я разрабатываю многопоточный сервер с пулом потоков. Эта система предназначена для использования постоянных TCP-соединений, поскольку клиенты будут поддерживать соединения вблизи 24/7. Проблема, с которой я сталкиваюсь, заключается в том, как управлять отключением. В настоящее время соединение происходит через «accept (listen_fd ....)» и присваивается структуре рабочего порядка. Эта структура сбрасывается в рабочую очередь и подбирается потоком. С этого момента этот поток посвящен текущему соединению. Мой код внутри нити:Выключение Постоянного TCP-соединения. (C многопоточный сервер)
/* Function which runs in a thread to handle a request */
void *
handle_req(void *in)
{
ssize_t n;
char read;
/* Convert the input to a workorder_ptr */
workorder_t *workorder_ptr = (workorder_t *)in;
while(!serv_shutdown
&& (n=recv(workorder_ptr->sock_fd,&read,1,0) != 0))
{
printf("Read a character: %c\n",read);
}
printf("Peer has shutdown.\n");
/* Free the workorder memory */
close(workorder_ptr->sock_fd);
free(workorder_ptr);
return NULL;
}
который просто слушает сокет и вторит символы бесконечно, и работает правильно, когда клиент разрывает соединение. Вы видите часть «! Serv_shutdown» в цикле while - это моя попытка заставить поток вырваться из своего цикла по сигналу выключения. Когда SIGINT пойман, глобальная переменная установлена в 1. К сожалению, программа в настоящее время блокирует оператор recv и не проверяет этот флаг до тех пор, пока не будет прочитан другой символ. Я хочу избежать этого, поскольку это может быть произвольное количество времени, прежде чем другой персонаж будет отправлен по этому соединению.
Кроме того, я прочитал в другом сообщении, что лучше использовать «выбрать», чем «принять», чтобы ждать сокета, но я не совсем понял. Будете ли вы делать выбор, чтобы подождать, а затем принять сразу после этого? Я не уверен, как select создает соединение сокета. Я спрашиваю об этом, потому что, если мое понимание выбора будет выяснено, возможно, оно относится к вопросу, который я задаю?
Также, как определить случай, когда соединение просто отключается?
Спасибо!
EDIT Я думаю, что, возможно, наконец, нашел решение, после дальнейшего копания:
Wake up thread blocked on accept() call
В принципе, я мог бы создать глобальную трубу и иметь каждый поток сделать выбор по своему socket_fd а также эта глобальная труба. Затем, когда сигнал пойман, я просто напишу что-нибудь в трубку. Все потоки должны быть разбужены, нет?