Блокировка исполняемых файлов: Windows делает, Linux - нет. Почему?


83

Я заметил, что когда файл выполняется в Windows (.exe или .dll), он заблокирован и не может быть удален, перемещен или изменен.

Linux, с другой стороны, не блокирует исполняемые файлы, и вы можете удалять, перемещать или изменять их.

Почему Windows блокируется, а Linux - нет? Есть ли преимущество в блокировке?


7
Существует утилита WhoLockMe, которая добавляет пункт меню в контекстное меню в проводнике, которое может отображать процесс (ы), блокирующий данный файл. Чрезвычайно полезно, когда вы получаете странные ошибки блокировки файлов. Изменить: я знаю, что это не отвечает на вопрос, но я подумал, что это было достаточно полезно в контексте, чтобы гарантировать отдельный ответ (в отличие от простого комментария).
JesperE,

Ответы:


106

В Linux есть механизм подсчета ссылок, поэтому вы можете удалить файл во время его выполнения, и он будет продолжать существовать до тех пор, пока какой-либо процесс (который ранее его открыл) имеет открытый дескриптор для него. Запись в каталоге для файла удаляется при его удалении, поэтому его больше нельзя открыть, но процессы, уже использующие этот файл, могут его использовать. После завершения всех процессов, использующих этот файл, он автоматически удаляется.

Windows не имеет такой возможности, поэтому она вынуждена блокировать файл до тех пор, пока все процессы, выполняющиеся из него, не завершатся.

Я считаю, что поведение Linux предпочтительнее. Вероятно, существуют некоторые глубокие архитектурные причины, но основная (и простая) причина, которую я считаю наиболее убедительной, заключается в том, что в Windows вы иногда не можете удалить файл, вы не знаете, почему, и все, что вы знаете, это то, что какой-то процесс хранит его в использовать. В Linux этого никогда не происходит.


2
Обратите внимание, что вы можете использовать такой инструмент, как Process Explorer в Windows, чтобы узнать, какой процесс использует файл / папку.
J c

15
Практическая причина в пользу поведения Linux заключается в том, что вы можете обновлять ОС и другое программное обеспечение в системе, пока она работает, и никогда / редко перезагружаться (вы даже можете переключить работающее ядро ​​без перезагрузки, это достаточно сложно, потому что оно вызывается только для приложений, критичных по времени безотказной работы).
joelhardi

7
«Windows не имеет такой возможности» ... вы уверены? Ядро NT основано на реф-подсчете объектов с дескрипторами и ссылками.
Адам Миц,

11
На самом деле в Windows есть 3 бита, которые определяют, что другой процесс может делать с файлом, пока он открыт. Файл можно удалить, пока он открыт, если установлен FILE_SHARE_DELETEбит. Я не думаю, что PE-загрузчик (который загружает EXE и DLL) устанавливает этот бит. Дескрипторы подсчитываются по ссылкам, и при удалении файл исчезает, когда отбрасывается последний дескриптор, но разница между этим и Unix заключается в том, что NT блокирует создание нового файла с тем же именем, когда это происходит.
asveikau

2
То, что говорит comonad, совершенно неверно, NTFS, конечно же, использует жесткие ссылки и всегда так делала, символические ссылки были добавлены в Windows Vista. Также совершенно неверно, что Windows не использует реф-копирование, она просто читает API-интерфейсы, такие как CreateFile, где ясно сказано, при каких обстоятельствах файлы удаляются и тому подобное. И это подходящее место для настоящего ответа на вопрос: CreateFile имеет аргумент, называемый dwShareMode, который управляет обязательной блокировкой открытых файлов и позволяет приложениям решать. Значение по умолчанию - эксклюзивная блокировка ...
Торстен Шёнинг

30

Насколько я знаю, Linux делает блокировку исполняемых файлов , когда они работают - однако, он блокирует инод . Это означает, что вы можете удалить «файл», но индексный дескриптор все еще находится в файловой системе, нетронутым, и все, что вы действительно удалили, - это ссылка.

Программы Unix все время думают о файловой системе таким образом: создают временный файл, открывают его, удаляют имя. Ваш файл все еще существует, но его имя доступно другим пользователям, и никто не может его увидеть.


"все время"? Есть примеры?
Mez,

4
Спросите Google о «безопасном временном файле unix», и вы найдете достаточно описаний метода, чтобы показать, что он хорошо известен и широко используется. Хотя у меня нет каких-либо конкретных примеров, я осмелюсь сказать, что это делает любое приложение, заботящееся о безопасности, которое использует временные файлы.
Дэйв Шерохман,

26

Linux блокирует файлы. Если вы попытаетесь перезаписать исполняемый файл, вы получите ETXTBUSY (текстовый файл занят). Однако вы можете удалить файл, и ядро ​​удалит файл, когда будет удалена последняя ссылка на него. (Если машина не была полностью выключена, эти файлы являются причиной сообщения «Удаленный индексный дескриптор имел нулевое время d» при проверке файловой системы, они не были полностью удалены, потому что выполняющийся процесс имел ссылку на них, и теперь они есть.)

Это имеет несколько основных преимуществ: вы можете обновить запущенный процесс, удалив исполняемый файл, заменив его, а затем перезапустив процесс. Даже init можно обновить таким образом, заменить исполняемый файл и отправить ему сигнал, и он сам повторно запустит exec () без перезагрузки. (Обычно это делается автоматически вашей системой управления пакетами в рамках обновления)

В Windows замена используемого файла представляет собой серьезную проблему, обычно требующую перезагрузки, чтобы убедиться, что никакие процессы не запущены.

Могут возникнуть некоторые проблемы, например, если у вас очень большой файл журнала, и вы удалите его, но забываете сообщить процессу, который вел журнал в этот файл, чтобы повторно открыть файл, он будет содержать ссылку, и вы удивитесь почему на вашем диске внезапно не стало намного больше свободного места.

Вы также можете использовать этот трюк в Linux для временных файлов. откройте файл, удалите его и продолжайте использовать файл. Когда ваш процесс завершится (по какой бы причине - даже при сбое питания), файл будет удален.

Такие программы, как lsof и fuser (или просто ковыряние в / proc // fd) могут показать вам, в каких процессах открываются файлы, у которых больше нет имени.


6

Я думаю, что linux / unix не использует один и тот же механизм блокировки, потому что они построены с нуля как многопользовательская система, что предполагает возможность использования одного и того же файла несколькими пользователями, возможно, даже для разных целей.

Есть ли преимущество в блокировке? Что ж, это могло бы уменьшить количество указателей, которыми должна будет управлять ОС, но теперь, в дни, сумма экономии довольно незначительна. Самое большое преимущество блокировки, которое я могу придумать, заключается в следующем: вы сохраняете некоторую видимую пользователю неоднозначность. Если пользователь a запускает двоичный файл, а пользователь b удаляет его, то фактический файл должен оставаться, пока процесс пользователя A не завершится. Тем не менее, если пользователь Б или любые другие пользователи будут искать его в файловой системе, они не смогут его найти, но он продолжит занимать место. Меня это не особо беспокоит.

Я думаю, что в большей степени это вопрос обратной совместимости с файловыми системами Windows.


«Windows» в этом контексте - это строка Windows NT. Он был разработан как многопользовательский преемник однопользовательской Windows 3.11. Сравните с Unix, который является однопользовательским преемником Multics.
MSalters

6

Я думаю, вы слишком категоричны в отношении Windows. Обычно он не выделяет пространство подкачки для части кода исполняемого файла. Вместо этого он блокирует все файлы и библиотеки DLL. Если отброшенные кодовые страницы снова понадобятся, они просто перезагружаются. Но с / SWAPRUN эти страницы хранятся в свопе. Это используется для исполняемых файлов на компакт-дисках или сетевых дисках. Следовательно, окнам не нужно блокировать эти файлы.

Для .NET посмотрите Shadow Copy .


1

Если исполняемый код в файле должен быть заблокирован или нет, - это дизайнерское решение, и MS просто решила заблокировать, потому что это имеет явные преимущества на практике: таким образом вам не нужно знать, какой код, в какой версии используется каким приложением. Это серьезная проблема с поведением Linux по умолчанию, которое просто игнорируется большинством людей. Если заменяются общесистемные библиотеки, вы не сможете легко узнать, какие приложения используют код таких библиотек, в большинстве случаев лучшее, что вы можете получить, - это то, что менеджер пакетов знает некоторых пользователей этих библиотек и перезапускает их. Но это работает только для общих и хорошо известных вещей, например, Postgres и его библиотек или чего-то подобного. Более интересны сценарии, если вы разрабатываете собственное приложение с использованием сторонних библиотек, и они заменяются, потому что в большинстве случаев менеджер пакетов просто не знает ваше приложение. И это ' Это проблема не только нативного кода C или чего-то подобного, это может случиться практически со всем: просто используйте httpd с mod_perl и некоторыми библиотеками Perl, установленными с помощью диспетчера пакетов, и позвольте диспетчеру пакетов обновлять эти библиотеки Perl по любой причине. Он не перезапустит ваш httpd просто потому, что не знает зависимостей. Примеров, подобных этому, множество, просто потому, что любой файл потенциально может содержать код, используемый в памяти любой средой выполнения, подумайте о Java, Python и всех подобных вещах.

Так что есть веские основания полагать, что блокировка файлов по умолчанию может быть хорошим выбором. Однако вам не нужно соглашаться с этими причинами.

Так что же сделал MS? Они просто создали API, который дает вызывающему приложению возможность решить, следует ли блокировать файлы или нет, но они решили, что значение этого API по умолчанию - обеспечить монопольную блокировку для первого вызывающего приложения. Взгляните на API CreateFile и егоdwShareMode аргумент. Это причина, по которой вы не сможете удалять файлы, используемые каким-либо приложением, оно просто не заботится о вашем варианте использования, использует значения по умолчанию и, следовательно, получает эксклюзивную блокировку Windows для файла.

Пожалуйста, не верьте людям, которые говорят вам, что Windows не использует подсчет ссылок на РУЧКАХ или не поддерживает жесткие ссылки или что-то подобное, это совершенно неправильно. Почти каждый API, использующий HANDLEs, документирует свое поведение в отношении подсчета ссылок, и вы можете легко прочитать почти в любой статье о NTFS, что он на самом деле поддерживает жесткие ссылки и всегда поддерживал. Начиная с Windows Vista, он также поддерживает символические ссылки, а поддержка жестких ссылок была улучшена за счет предоставления API-интерфейсов для чтения всех из них для данного файла и т. Д.

Кроме того, вы можете просто взглянуть на структуры, используемые для описания файла, например, в Ext4 по сравнению со структурами NTFS , которые имеют много общего. Оба работают с концепцией экстентов, которая отделяет данные от атрибутов, таких как имя файла, а inodes - это в значительной степени просто другое имя для более старой, но похожей концепции этого. Даже Википедия перечисляет обе файловые системы в своей статье. .

В Windows действительно много проблем с блокировкой файлов по сравнению с другими операционными системами в сети, как и с дефрагментацией. Некоторые из этих FUD можно исключить, просто прочитав немного в Википедии .


Рассуждения об управлении версиями общих зависимостей неуместны. Вам придется решать эти проблемы, даже если для их обновления требуется перезагрузка. В Windows у него даже есть имя: DLL hell. Кроме того, описываемое вами поведение среды выполнения полностью обрабатывается случаем Linux, когда файл уже загружен в память и остается доступным; приложение будет работать со старой версией до тех пор, пока не перезапустится, так же, как когда Windows принудительно перезагружает файл, чтобы разблокировать файл. На этом фронте нет никакого преимущества.
jpmc26

DLL hell, конечно, полностью упускает суть, и у нас больше нет 90-х, просто читайте о таких вещах WinSxSи т. Кроме того, речь идет не о загрузке вещей в память и хранении их там, Windows делает именно это при необходимости, а о знании и решении, следует ли заменять файлы или нет, и о том, кто несет ответственность за это. Windows-API просто позволяет решать первому пользователю файла, и это имеет большой смысл.
Thorsten Schöning

Но это моя точка зрения: решение, какую версию DLL использовать, - это часть ада DLL. Назовите это «адом зависимости», если хотите отличаться от некоторых старых идиосинкразических особенностей Windows. Тем не менее, блокировка исполняемых файлов по умолчанию не помогает в управлении общими зависимостями. Вообще. То, что зависит от конкретного файла, может даже не работать, когда вы пытаетесь его обновить; нет никакой дополнительной безопасности. Есть 2 варианта с общими зависимостями: бесплатный для всех, который может сломаться при попытке запустить его, или менеджер пакетов, который может помешать вам установить что-то.
jpmc26

Этот вопрос не о том, какой EXE или DLL использовать, а о том, что происходит потом по умолчанию и почему. Вы обсуждаете совершенно другую тему. Блокировка используется после решения, какой EXE или DLL выполнить, чтобы получить некоторый уровень дополнительного управления первым пользователем, которым является сама Windows в этом примере, и сообщить другим об этом элементе управления. И запрет на то, чтобы «другие» по какой-то причине удаляли или записывали файлы в файлы, которые нужны Windows и поэтому блокирует их, это, конечно, механизм для дополнительной координации.
Thorsten Schöning

1
Некоторые EXE или DLL, скорее всего, и так не находятся «в памяти», а по умолчанию отображаются в них. Для сопоставления необходимо, чтобы содержимое файла было доступно, поэтому произвольная его замена по умолчанию считается небезопасной, и нужно знать, что вы делаете. Что, очевидно, не так, если вас удивят заблокированные EXE или DLL. OTOH, все остальные файлы заблокированы только по умолчанию, не обязательно, поэтому приложения могут решать, разрешают ли они вам операции записи или удаления, в зависимости от их варианта использования. Разработчики приложений должны лучше, чем произвольные пользователи, знать, как они используют свои файлы и какие операции безопасны и когда.
Thorsten Schöning

0

Варианты NT имеют

открытые файлы

команда, которая покажет, какие процессы имеют дескрипторы для каких файлов. Однако это требует включения глобального флага системы 'поддерживать список объектов'

openfiles / local /?

расскажет, как это сделать, а также о том, что это приведет к снижению производительности.


0

Исполняемые файлы постепенно отображаются в память при запуске. Это означает, что части исполняемого файла загружаются по мере необходимости. Если файл выгружается до отображения всех разделов, это может вызвать серьезную нестабильность.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.