В Windows, как заставить хэш C возвращаться, даже если нет ожидающих ввода? - PullRequest
0 голосов
/ 31 октября 2018

В программе Windows с двумя потоками: thread1 и thread2.

Когда thread1 заблокирован в вызове fread(buffer, 1, 10, stdin) в ожидании ввода, возможно ли сделать что-то из thread2, чтобы заставить fread вернуться?

Пока я пытался дозвониться до fclose(stdin) с thread2, но, похоже, это не работает Программа застревает при вызове fclose до тех пор, пока какой-либо ввод не станет доступен в потоке stdin.

То, чего я пытаюсь достичь, это завершить thread1 изящно, вместо того, чтобы просто убить его с помощью TerminateThread, потому что есть некоторая работа, которую thread1 должен сделать в конце.

Еще одна вещь, которую следует учитывать, это то, что stdin - это один конец именованного канала. У меня нет контроля над программой на другом конце канала.
Что мне нужно, так это просто отключить мою программу от конца канала (stdin в данном случае).

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Если вы не можете использовать CancelSynchronousIo, вы можете закрыть основной дескриптор файла с помощью CloseHandle, например:

CloseHandle((HANDLE)_get_osfhandle(_fileno(stdin))) ;

Это должно привести к возвращению fread.

0 голосов
/ 31 октября 2018

Звонить fclose(stdin) - очень плохая идея; это вызывает неопределенное поведение, если это происходит до fread (что не упорядочено по отношению к нему) или если поток, вызывающий fread, делает что-либо еще с stdin после возврата fread, и это не разблокирует fread, поскольку fclose не может продолжить работу, пока не получит блокировку на stdin, исключая текущую fread.

stdio просто принципиально не подходит для того, что вы хотите здесь делать. Вы можете исправить это, перенаправив через второй канал, с еще одним потоком, читающим из stdin и записывающим в ваш новый канал. Затем вы можете прервать fread на конце чтения канала, закрыв конец записи. Дополнительная нить все равно застрянет, но на самом деле это не имеет значения, если вы все равно будете завершать. В качестве альтернативы (и это, вероятно, чище) вы могли бы использовать файловые дескрипторы (или файловые дескрипторы Windows) вместо stdio и poll (или эквивалент Windows), чтобы определить, есть ли ввод для чтения. Вы могли бы объединить эти подходы, чтобы поместить логику дескриптора файла, специфичную для Windows, в дополнительный поток (таким образом, имея возможность его чистого завершения) и продолжать использовать переносимый stdio в потоке логики вашей программы.

...