У меня есть приложение, которое работает на большом количестве процессоров. На процессоре 0 у меня есть функция, которая записывает данные в сокет, если он открыт. Эта функция выполняется в цикле в отдельном потоке на процессоре 0, т. е. процессор 0 отвечает за свою собственную рабочую нагрузку и имеет дополнительный поток, обеспечивающий связь на сокете.
//This function runs on a loop, called every 1.5 seconds
void T_main_loop(const int& client_socket_id, bool* exit_flag)
{
//Check that socket still connected.
int error_code;
socklen_t error_code_size = sizeof(error_code);
getsockopt(client_socket_id, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
if (error_code == 0)
{
//send some data
int valsend = send(client_socket_id , data , size_of_data , 0);
}
else
{
*(exit_flag) = false; //This is used for some external logic.
//Can I fix the broklen pipe here somehow?
}
}
Когда клиентский сокет закрывается, программа должна просто игнорировать ошибку, и это стандартное поведение, насколько мне известно.
Однако я использую внешнюю библиотеку (PETSc), которая каким-то образом обнаруживает ошибку сломанной трубы и закрывает всю параллельную (MPI) среду:
[0]PETSC ERROR: Caught signal number 13 Broken Pipe: Likely while reading or writing to a socket
Я хотел бы оставить конфигурацию этой библиотеки совершенно нетронутой, если это вообще возможно. Открыт для любых надежных обходных путей, которые возможны.
SO_ERROR
для проверки состояния подключения? Вы вообще не должны этого делать. Просто вызовитеsend()
безоговорочно, и если это не удастся,errno
сообщит вам, почему, напримерEBADF
/ENOTSOCK
,ECONNRESET
,ENOTCONN
,EPIPE
и т. д. Вместо этого используйте это для обнаружения разрыва соединения. - person Remy Lebeau   schedule 16.01.2020void T_main_loop(const int& client_socket_id, bool* exit_flag) { int valsend = send(client_socket_id, data, size_of_data, MSG_NOSIGNAL); if (valsend < 0) { /* check errno if needed */ *exit_flag = false; } }
- person Remy Lebeau   schedule 16.01.2020SO_ERROR
, вы не знаете, какая предыдущая операция не удалась или когда она не удалась. И вам не нужно знать. При таком подходе вы хотите отправить данные СЕЙЧАС, а СЕЙЧАС это не удается, поэтому действуйте независимо от того, что произошло ДО этого. - person Remy Lebeau   schedule 16.01.2020