Это старый пост, но я искал хороший способ сделать это и не нашел ни одного.
Возможно, это поможет кому-то в подобной ситуации ..
Я делаю это в Windows, но, возможно, это также возможно в osx / linux с использованием именованных мьютексов pthread, хотя я не знаю политики в отношении того, как обрабатываются такие мьютексы, если приложение завершается, что крайне важно для этого. техника.
Проблема с использованием одного флага заключается в том, что он не работает в ситуации, когда может быть несколько экземпляров приложения:
- Приложение 1 запускается. Устанавливает флаг «не выключен должным образом».
- Приложение 2 запускается. Видит, что он не выключился, потому что флаг установлен, и думает, что произошел сбой, когда его не было.
Это немного сложно обойти, и, возможно, есть несколько способов сделать это, но этот метод пока работает нормально (по крайней мере, в Windows):
Создать глобальный именованный мьютекс с вновь созданным GUID / UUID в качестве имени.
GUID различен для каждого экземпляра приложения, поэтому у каждого будет уникальное имя mutex.
GUID записывается в файл, содержащий список GUID.
Если приложение закрывается правильно, вы удаляете GUID из файла, и мьютекс закрывается.
В случае сбоя или прекращения работы приложения GUID не удаляется из файла, НО мьютекс уничтожается ОС, и приложение не должно это делать.
Когда вы запускаете приложение, вы можете запустить GUID в списке и вызвать для них OpenMutex и мьютексы, которые не существуют (GetLastError возвращает ERROR_FILE_NOT_FOUND). Любые несуществующие взаимные исключения указывают, что произошел сбой / завершение.
Все GUID, которые имеют это свойство, могут быть удалены из списка на этом этапе.
Еще одна вещь, которую вы можете сделать, - это удалить неправильные GUID из списка при правильном завершении работы.
Это обходит следующую ситуацию:
- Приложение 1 запускается
- Приложение 2 запускается
- Приложение 1 вылетает
- Приложение 2 успешно закрыто
- Приложение 3 запущено.
Когда приложение 3 запускается, оно не должно сообщать о том, что произошел сбой, потому что последнее завершение работы прошло успешно.
Я также реализовал своего рода спин-блокировку при получении доступа к файлу, содержащему идентификаторы GUID, которые будут выполняться после истечения времени ожидания и не будут добавлять guid приложения в файл. В таких случаях, вероятно, лучше всего запустить приложение и потерять обнаружение сбоев, а не запускать приложение вообще.
Другие предупреждения должны сохранять блокировку файла при запросе и обновлении файла, чтобы избежать условий гонки. В Windows это предотвращает использование файловых потоков stl, так как вам нужно будет обрезать файл после прочтения, при этом сохраняя монопольный доступ к файлу.