У меня есть данные, хранящиеся в памяти, которые я хочу открыть. Я создаю временный файл и fork xdg-open
на ubuntu, чтобы открыть файл, используя стандартное приложение. Я хочу удалить временный файл после закрытия программы. Проблема в том, что xdg-open
сам открывает другой процесс и немедленно уходит. Следовательно, я не знаю, какой процесс открыл файл. Я попытался получить эксклюзивную блокировку с flock
, а также попытался сделать unlink
файл после того, как я ожидаю 20 srcs (чтобы убедиться, что другой процесс сначала открывает файл), вызовы преуспевают, а открытая программа просто закрывает файл. Я хочу подождать, пока программа не будет закрыта, а затем удалите файл. Кто-нибудь знает, как это сделать?Как удалить файл после завершения другого процесса?
ответ
Когда XDG открыть не полагаться на суффикс, вы можете использовать
fd = open(filename, O_RDONLY|O_CLOEXEC);
unlink(filename);
system("xdg-open /proc/%u/fd/%u", getpid(), fd); /* pseudo-code! system is not printf() like! */
close(fd);
Если 'xdg-open' (или двоичный код вызывает для открытия файла) вилки для выполнения фактическое приложение в дочернем процессе и выходит из него, вызов 'system()' может возвращаться, а дескриптор закрывается (и поэтому исчезает) до того, как фактическое приложение имеет возможность попробовать его открыть. В зависимости от того, как реализован «xdg-open», обычно это скрипт, исполняющий двоичный файл, зависящий от рабочего стола, - это может работать или не работать. –
Вы можете использовать либо Inotify (see man 7 inotify
) или файл аренды (see man 2 fcntl
, Leases section) для обнаружения, когда другие процессы открыть и закрыть файл (с Inotify), или определить, открыт ли файл другими процессами (файловая аренда).
Основная проблема заключается в том, что xdg-open
обычно представляет собой скрипт, который исследует среду (и, возможно, целевой файл), затем выполняет двоичный файл (который, в свою очередь, может проверить целевой файл и выполнить другой двоичный файл), и возможно, что один или несколько этапов здесь вилка и немедленно выйти, при этом клиентский процесс продолжает цепочку.
Это означает, что момент времени, когда system()
возвращается, в основном не имеет значения. Целевой файл может быть или не быть открыт потенциальным приложением в этой точке; мы просто не знаем и не знаем этого.
Одним из вариантов было бы создать отдельную группу процессов (сеанс) и следить за сеансом, сохраняя исходный файл до тех пор, пока существует группа процессов. Однако предполагается, что ни один из скриптов или двоичных файлов в цепочке xdg-open
не создает свои собственные сеансы. (Я не знаю, если они делают, есть так много различных реализаций. - каждая среда рабочего стола использует свой собственный двоичный файл, с xdg-open
быть оберткой совместимости вокруг них)
На практике это означало бы заменить system()
с вашим собственная реализация с использованием fork()
, setsid()
, exec*()
и waitpid()
и waitid()
; последний в цикле с коротким сном для обнаружения, когда в группе процессов больше нет процессов.
Другой вариант - выполнить команду, затем (fork дочерний процесс) дождаться определенного периода - скажем, до тех пор, пока средний пользователь может терпеть дождаться загрузки файла; несколько секунд, другими словами -, затем начните проверку, все еще используется файл. После того, как файл больше не используется, он может быть отсоединен.
С inotify()
вы должны назначить часы перед выполнением команды xdg-open
, а затем наблюдать и открывать и закрывать оба. Поскольку возможно, что xdg-open
исследует целевой файл для выбора приложения, вы не можете предположить, что первое закрытие является окончательным закрытием; вам также нужно дождаться определенного периода, указанного выше, чтобы убедиться, что приложение-открытая цепочка завершена. Затем, если есть столько закрытий, сколько было открыто, файл может быть отсоединен. В противном случае вы будете ждать оставшихся закрытий и отключите файл после последнего.
С file leases метод немного проще, но и более ограничен. Вы можете получать только файлы в обычных файлах, принадлежащих самому пользователю. Вы можете получить аренду для чтения только в том случае, если файл не открыт для записи каким-либо процессом (включая другие дескрипторы этого же процесса). Вы можете получить аренду записи только в том случае, если файл вообще не открыт каким-либо процессом (включая другие дескрипторы файлов этим же процессом). В то время как вы держите аренду, любой другой процесс, открывающий файл (если вы держите аренду в лизинге), или пытаетесь его изменить (если вы держите на нем чтение или запись на нем), выдается сигнал SIGIO
(по умолчанию вы может изменить его на сигнал в реальном времени), который должен быть отправлен владельцу аренды. Он имеет до /proc/sys/fs/lease-break-time
секунд, чтобы понизить или отпустить аренду, пока ядро не сломает его принудительно; в течение этого времени модификатор открытия/файла будет заблокирован по вызову open()
/truncate()
.
Перед тем, как исполнить xdg-open
, вы можете попробовать получить договор аренды на файл. Если это удастся, вы знаете, что это единственный дескриптор открытого файла. После того, как вызывается xdg-open
, аренда будет нарушена, когда файл будет открыт (или проверен одним из двоичных файлов); вы можете просто освободить аренду до звонка, чтобы избежать хлопот. После того, как прошло соответствующее количество секунд с момента выполнения xdg-open
- количества времени, которое человек ожидал, когда приложение начнет открывать файл, - вы начинаете периодически проверять, открыт ли файл другим процессом по пытаясь получить на него договор аренды. Если листы записи успешно завершены, и прошло достаточно времени, когда вы запустили xdg-open
, то вы знаете, что либо «пользователь-пользователь» стал бы слишком расстроен, чтобы ждать, пока файл будет открыт, или приложение уже закрыто файл, и поэтому файл может быть отсоединен.
Все вышеперечисленное может быть объединено, чтобы получить как параноидальное, как вы хотите, но лично я считаю, что подход, моделирующий поведение человека, является наиболее надежным. Я бы лично сделал ограничение по времени (и записывал интервал попытки аренды) легко настраиваемым, с примерно 10 секундами и 1 секундой по умолчанию, соответственно.
Наконец, если использование ресурсов вызывает беспокойство, я рекомендую написать отдельный вспомогательный двоичный файл, чтобы управлять этим для вас. В основном, вместо запуска xdg-open [OPTIONS] FILENAME
, вы запускаете /usr/lib/myapp/open DELAY INTERVAL [OPTIONS] FILENAME
. Двоичные вилки /usr/lib/myapp/open
и сразу же выходят. Детский процесс выполняет xdg-open
и выполняет описанную выше процедуру, чтобы дождаться, пока файл не будет отсоединен. Каждый из двоичных файлов /usr/lib/myapp/open
требует очень мало данных (минимальный размер резидентного набора) и ресурсов (они в основном спят), поэтому даже имея несколько десятков из них в памяти, не будет сильно стекать даже на встроенную машину Linux.
Если есть интерес, я могу добавить пример C реализации /usr/lib/myapp/open
здесь. (Просто дайте мне знать, какой из трех подходов наиболее интересен - мониторинг группы процессов, inotify или файловая аренда.)
- 1. Удалить файл после завершения сценария
- 2. Файл процесса администратора Django после завершения загрузки
- 3. Убейте команду cmd после завершения процесса завершения процесса?
- 4. В.Б MsgBox после завершения процесса
- 5. Как очистить подпроцесс.Появление экземпляров после завершения процесса
- 6. Чтение stderr после завершения процесса
- 7. Перезапустить mysql после завершения процесса
- 8. C# Async Issue - Файл недоступен - Ожидание другого процесса для завершения
- 9. Получить VMPeak после завершения процесса
- 10. Ждите завершения процесса
- 11. Как сохранить графики matplotlib после завершения процесса
- 12. Как продолжить выполнение процесса после завершения потоков?
- 13. Как показать MsgBox после завершения процесса архиватора,
- 14. Как убить терминал после завершения процесса
- 15. Как остановить выполнение процесса после его завершения
- 16. Удалить анимацию после завершения
- 17. Ошибка завершения задачи async после родительского процесса
- 18. Inno Setup: выполнить командный/пакетный файл после завершения процесса установки
- 19. Как удалить файл образа процесса?
- 20. ждет завершения процесса
- 21. Как просмотреть содержимое/proc/[pid]/status после завершения процесса завершения процесса?
- 22. Исходный файл не скомпилирован, даже после завершения процесса компиляции
- 23. как ждать завершения процесса
- 24. Освобождение процесса Excel * 32 после завершения операции
- 25. Как удалить файл после завершения потока в java?
- 26. Как сделать .BAT-файл удалить его после завершения?
- 27. Как удалить тестовый файл после завершения тестирования в python?
- 28. Golang Как удалить сгенерированный zip-файл после завершения загрузки пользователя?
- 29. Как выполнить метод только после другого завершения?
- 30. Как выполнить функцию javascript после завершения другого?
Возможно, создается избыточный массив указателей файлов, которые вилки будут обновлять до открытия файла? – ciphermagi
Вы можете в принципе удалить (отменить связь) файл немедленно. Это «удалит» файл с логической точки зрения, но физическое хранилище останется до тех пор, пока другая программа откроет его. Все, что пытается сделать другой процесс, по-прежнему будет работать. Когда другой процесс закрывает файл и выходит, от него ничего не остается. – Damon
@ Дамон да, как я уже говорил, я это пробовал, но это заставляет приложение закрывать файл. – chacham15