Системный вызов select - это способ подождать, пока дескрипторы файлов не изменят состояние, в то время как программам больше нечего делать. Основное использование предназначено для серверных приложений, которые открывают несколько файловых дескрипторов, а затем ждут, что с ними что-то будет делать (принимают новые соединения, читают запросы или отправляют ответы). Эти файловые дескрипторы будут открыты в неблокирующем режиме io, так что процесс сервера не будет зависать в системном вызове в любое время.
Это дополнительно означает, что нет необходимости в отдельных потоках, потому что вся работа, которая может быть выполнена в потоке, может быть выполнена до вызова select. И если работа занимает больше времени, чем ее можно прервать, выберите вызов с тайм-аутом = {0,0}, дескрипторы файлов будут обработаны, а затем работа возобновится.
Теперь вы закрываете дескриптор файла в другом потоке. Почему у вас вообще есть этот дополнительный поток, и почему он должен закрывать файловый дескриптор?
Стандарт POSIX не дает никаких подсказок, что происходит в этом случае, поэтому то, что вы делаете, - НЕОПРЕДЕЛЕННОЕ ПОВЕДЕНИЕ. Ожидайте, что результат будет очень разным в разных операционных системах и даже в разных версиях одной и той же ОС.
С уважением, Бодо