Могу ли я написать в закрытую розетку и принудительно исправить ошибку сломанной трубы? - PullRequest
1 голос
/ 14 января 2020

У меня есть приложение, которое работает на большом количестве процессоров. На процессоре 0 у меня есть функция, которая записывает данные в сокет, если он открыт. Эта функция выполняется в al oop в отдельном потоке на процессоре 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?
    }
}

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

Однако я использую внешнюю библиотеку (PETS c), которая каким-то образом обнаруживает сломанный канал ошибка и закрытие всей параллельной (MPI) среды:

[0]PETSC ERROR: Caught signal number 13 Broken Pipe: Likely while reading or writing to a socket

Я хотел бы оставить конфигурацию этой библиотеки полностью без изменений, если это вообще возможно. Открыты для любых возможных обходных путей.

1 Ответ

2 голосов
/ 14 января 2020

По умолчанию ОС отправляет поток SIGPIPE, если он пытается записать в (наполовину) закрытый канал или сокет.

Один из вариантов отключения сигнала - сделать signal(SIGPIPE, SIG_IGN);.

Другой вариант - использовать флаг MSG_NOSIGNAL для send, например, send(..., MSG_NOSIGNAL);.

...