Это проблема, которую я в настоящее время должен решить в отношении неискушенных конечных пользователей, которые могут сделать много вещей, чтобы расстроить разумные предложения, сделанные предыдущими участниками. Неискушенный конечный пользователь может сделать по крайней мере эти вещи, и даже больше:
1) Недостаточно компьютерных знаний для настройки синхронизации по времени ntp
2) Установите часы своего компьютера на домашние часы или часы мобильного телефона, которые являются неправильными
3) В Windows XP случайно отключите синхронизацию времени ntp и не знаете, как включить его снова, или неправильно установите дату на компьютере, в этом случае Windows ntp не работает
4) Аккумуляторная батарея компьютера разрядилась, поэтому компьютер всегда запускается в 1970 году!
5) Пользователь вывозит свой ноутбук за границу и временно устанавливает часы ноутбука на местное время, но не меняет часовой пояс, поэтому теперь компьютер вернет неправильное время utc !!!
Так что вашей программе придется управлять временем, и, конечно, вы хотите сделать это с минимальными издержками.
Предположим, что двум конечным пользователям, запускающим ваши программы, нужны программы, которые будут делать что-то в одно и то же время в будущем.
Я предлагаю эту схему, которая берет некоторые идеи из работы cron-заданий, я был бы рад, если бы кто-нибудь мог предложить улучшения этой идеи.
1) Когда ваше приложение запускается, оно синхронизирует свое собственное внутреннее время utc с ntp через мыльный вызов на сторонний сервер или на ваш собственный сервер времени (который вы можете самостоятельно поддерживать во времени с помощью ntp).
2) После этого добавляется время, оставшееся от системных часов, для поддержания времени. Если требования строгие, вам может потребоваться повторять синхронизацию ntp с интервалами.
3) Затем приложение просматривает список будущих заданий, которые необходимо выполнить в срок. Нужно знать самую раннюю работу.
4) Затем он создает поток, который помещает в спящий режим на период времени, предшествующий самой ранней работе, за вычетом запаса прочности, который в зависимости от ваших требований может составлять 10 минут вперед, час или два вперед и т. Д. .
5) Когда поток просыпается, он перепроверяет абсолютное время с последующим вызовом мыла, а затем полагается на часы системного времени, чтобы добавить истекшее время, пока оно не достигнет времени, когда должно быть выполнено первое задание.
6) Как только задание запускается (запускается в другом потоке), поток контроля времени вычисляет время следующего задания и снова переводит себя в спящий режим на время.
Улучшения к идее:
1) Пользователь может закрыть ваше приложение перед должной работой, поэтому вам может понадобиться фоновый процесс или служба, которая использует ту же схему синхронизации, что и выше, для независимого мониторинга ваших списков работ, хранящихся в базе данных или файле, и запустите приложение вовремя. (В Windows порождает процесс приложения)
2) Ваше приложение может добавлять новые, более ранние задания на лету или удалять задания, поэтому ваш спящий поток, вероятно, должен быть доступен для повторного расчета для нового более раннего задания или для задания, следующего за удаленным заданием. В Win32 вы могли бы сделать это своим потоком, ожидающим время ожидания события, которое вы устанавливаете, чтобы заставить его пересчитать время ожидания. В Linux, без сомнения, есть похожий механизм.
3) Чтобы время вызова Soap получало время, запишите, когда мыло отправлено и когда получен ответ. Если время выполнения заказа слишком велико, вы не можете рассчитывать на это время, и вам может потребоваться повторить вызов, или вы можете пойти на компромисс. Например, если Soap сообщает, что часы компьютера работают на 5 минут быстрее, а сам вызов Soap занял минуту, чтобы ответить, то можно с уверенностью сказать, что часы компьютера работают как минимум на 4 минуты.