#windows #c #mingw #unix #linux
Программа на C, ОС — Windows XP, компилятор — MinGW GCC 3.4.5. Нужен аналог alarm() — SIGALRM. Этого в MinGW нет. Вместо alarm() использовал timeSetEvent() из libwinmm.a. Callback отрабатывает, но read() (на самом деле gets() с консоли) не прерывается (по SIGINT (^C) — прерывается). Вызов raise (SIGILL) из Callback не помогает. Похоже, Callback и основная программа — это разные потоки, а raise генерит сигнал в текущем потоке, то есть в потоке Callback. Как послать сигнал (в реализации MinGW) в другой поток? Заодно, как определить текущий thread (к сожалению, в Windows я не силен)? Каким еще образом можно прервать ожидание ввода? Желательно получить : read() == -1; errno == EINTR. Собственно, задача состоит в эмуляции alarm(), то есть вызове подпрограммы через заданное время. Крайне полезный побочный эффект — прерывание системного вызова (особенно ожидающего события), во время работы которого (системного вызова) сработал таймер. Решение для конкретного случая с использованием setjmp() очевидно, хотелось бы обойтись без него (или максимально спрятать его на уровне вызова alarm()). Уточнение. @duff, @тимур, благодарю за внимание. Хочу сделать alarm() для MinGW (Windows) с поведением аналогично SYSV Unix (то есть блокируемый системный вызов (например read() при срабатывании таймера прерывается). Вообще говоря, при вызове alarm() неизвестно, будет ли блокировка на сокете, на консоли или на паузе (Sleep()). Желательно прерывать ЛЮБОЕ ожидание. К сожалению, я практически не владею WinAPI, поэтому не знаю, как из вызванной по срабатыванию таймера CallBack функции: определить, находится ли поток (thread) с main() в состоянии ожидания. (ждет какого-либо семафора в ядре?) (предполагаем однопоточную с точки зрения программиста, вызывающего alarm(), схему). прервать ожидание с возвратом из системного вызова (наверное правильно говорить о функции WinAPI ?) с осмысленным результатом. Если можно поподробнее о том, где почитать о kbhit, ReadFile, CancelIO. Надеюсь правильно понял (особенно ХэшКод). Благодарю всех за советы по WinAPI, буду изучать и пробовать. Искренне Ваш, avp
Ответы
Ответ 1
Чтобы не блокировать ввод, можно попробовать: для POSIX - kbhit + select; для WinAPI - ReadFile + CancelIO. Еще раз перечитал вопрос. Если просто нужно прервать чтение по таймеру, то select — лучший вариант. Чтобы реализовать alarm() для MinGW, придется работать с Windows API (я другого способа не вижу). Вам потребуются CreateThread WaitForSingleObject SetWaitableTimer Об этих и других функциях, которые понадобятся, а также примерах их использования лучше всего читать прямо в MSDN.Ответ 2
На Windows API вызов подпрограммы через определенный промежуток времени достигается с помощью функции SetTimer, которая при обращении получает адрес отложенной функции (callback), а уведомление о событии в другой поток передается функцией SetEvent.
Комментариев нет:
Отправить комментарий