Блокування виконуваних файлів: 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 робить блокування виконуваних файлів , коли вони працюють - проте, він блокує инод . Це означає, що ви можете видалити "файл", але inode все ще знаходиться у файловій системі, недоторканий, і все, що ви дійсно видалили, - це посилання.

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


"весь час"? Будь-які приклади?
Мез

4
Запитайте google про "тимчасовий захищений файл unix", і ви знайдете достатньо описів техніки, щоб показати, що вона добре відома та широко використовується. Хоча у мене немає конкретних прикладів, я наважусь сказати, що це робить будь-яка програма з урахуванням безпеки, яка використовує тимчасові файли.
Дейв Шерохман

26

Linux дійсно блокує файли. Якщо ви спробуєте перезаписати файл, який виконується, ви отримаєте "ETXTBUSY" (Текстовий файл зайнятий). Однак ви можете видалити файл, і ядро ​​видалить файл, коли буде видалено останнє посилання на нього. (Якщо машина не була чисто вимкнена, ці файли є причиною повідомлень "Видалений inode мав нульовий час", коли перевіряється файлова система, вони не були повністю видалені, оскільки запущений процес мав посилання на них, і зараз вони є.)

Це має кілька основних переваг, ви можете оновити процес, який працює, видаливши виконуваний файл, замінивши його, а потім перезапустивши процес. Навіть init можна оновити таким чином, замінити виконуваний файл і надіслати йому сигнал, і він повторно виконає () сам, не вимагаючи перезавантаження. (Це зазвичай робиться автоматично вашою системою управління пакетами в рамках оновлення)

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

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

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

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


6

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

Чи є перевага блокування? Ну, це може, можливо, зменшити кількість покажчиків, якими ОС повинна була б керувати, але зараз кількість заощаджень досить незначна. Найбільша перевага, яку я можу придумати перед блокуванням, полягає в наступному: ви економите деяку невизначеність, яку можна переглянути. Якщо користувач a запускає двійковий файл, а користувач b видаляє його, тоді фактичний файл повинен залишатися, поки процес користувача A не завершиться. Однак, якщо користувач B або будь-який інший користувач шукає файлову систему, він не зможе його знайти, але він і надалі займе місце. Мене насправді не дуже турбує.

Я думаю, що в основному це більше питання про зворотну сумісність з файловими системами вікна.


"Windows" у цьому контексті - це лінія Windows NT. Він був розроблений як багатокористувацький наступник однокористувацької Windows 3.11. Порівняйте з Unix, який є однокористувацьким наступником Multics.
MSalters

6

Я думаю, ти занадто абсолютний щодо Windows. Зазвичай він не виділяє простір підкачки для кодової частини виконуваного файлу. Натомість він тримає замок на виконуваних файлах та бібліотеках DLL. Якщо відкинуті кодові сторінки потрібні знову, вони просто перезавантажуються. Але з / SWAPRUN ці сторінки зберігаються в місцях обміну. Це використовується для виконуваних файлів на компакт-дисках або мережевих дисках. Отже, Windows не потребує блокування цих файлів.

Для .NET подивіться на Тіньова копія .


1

Якщо виконаний код у файлі повинен бути заблокований чи ні - це рішення проекту, і MS просто вирішила заблокувати, оскільки це має очевидні переваги на практиці: Таким чином, вам не потрібно знати, який код у якій версії використовується яким додатком. Це головна проблема поведінки за замовчуванням Linux, яку більшість людей просто ігнорує. Якщо загальносистемні бібліотеки замінено, ви не зможете легко дізнатись, які програми використовують код таких бібліотек. Найчастіше найкраще, що ви можете отримати, - це те, що менеджер пакетів знає деяких користувачів цих бібліотек і перезапускає їх. Але це працює лише для загальних і добре відомих речей, таких як, можливо, Postgres та його бібліотеки чи подібні. Більш цікаві сценарії, якщо ви розробляєте свій власний додаток для деяких сторонніх бібліотек, і їх замінюють, оскільки більшість випадків менеджер пакунків просто не знає вашого додатка. І це ' Це проблема не тільки власного коду C або подібного, це може трапитися майже з усім: просто використовуйте httpd з mod_perl та деякими бібліотеками Perl, встановленими за допомогою менеджера пакунків, і нехай менеджер пакетів оновлює ці бібліотеки Perl з будь-якої причини. Він не перезапустить ваш httpd, просто тому, що не знає залежностей. Існує безліч прикладів, подібних до цього, просто тому, що будь-який файл потенційно може містити код, який використовується в пам’яті будь-яким середовищем виконання, подумайте про Java, Python та всі подібні речі.

Тож є вагома причина думати, що блокування файлів за замовчуванням може бути хорошим вибором. Однак вам не потрібно погоджуватися з цими причинами.

То що зробив РС? Вони просто створили API, який надає програмі, що викликає, можливість вирішити, чи слід блокувати файли чи ні, але вони вирішили, що значення цього API за замовчуванням полягає у забезпеченні ексклюзивного блокування для першої програми, що викликає. Погляньте на API навколо CreateFile та його dwShareModeаргументи. Саме тому у вас може не бути можливості видалити файли, що використовуються якимось додатком, він просто не дбає про ваш варіант використання, використовував значення за замовчуванням і, отже, отримав ексклюзивне блокування Windows для файлу.

Будь ласка, не вірте тим, що люди, які говорять вам щось про Windows, не використовують перерахування посилань на HANDLE або не підтримують жорсткі посилання або подібні, що є абсолютно неправильним. Майже кожен API, який використовує HANDLEs, документує свою поведінку щодо підрахунку реф., І ви можете легко прочитати майже в будь-якій статті про NTFS, що він фактично підтримує жорсткі посилання і завжди. Починаючи з Windows Vista, він також підтримує символічні посилання, а підтримку твердих посилань покращено завдяки наданню API для зчитування всіх даних для певного файлу тощо.

Крім того, ви можете просто захотіти поглянути на структури, що використовуються для опису файлу, наприклад, у Ext4, порівняно із структурами NTFS , які мають багато спільного. Обидва вони працюють з концепцією extents, яка відокремлює дані від таких атрибутів, як ім'я файлу, а inodes - це в основному просто інша назва для більш старої, але подібної концепції цього. Навіть Вікіпедія перераховує обидві файлові системи у своїй статті .

Насправді багато FUD щодо блокування файлів у Windows, порівняно з іншими ОС в мережі, як і дефрагментація. Дещо з цього FUD можна виключити, просто прочитавши трохи у Вікіпедії .


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

Пекло DLL, звичайно, повністю втрачає сенс, і у нас вже немає 90-х, просто читайте про такі речі WinSxSта інше. Крім того, мова не йде про завантаження речей у пам’ять та збереження їх там, Windows робить саме це, а також за необхідності, а про те, щоб знати і вирішити, чи слід замінювати файли чи ні, і хто відповідає за це. API Windows просто дозволяє першому користувачеві файлу вирішити, і це має великий сенс.
Торстен

Але в цьому моя суть: вирішення, яку версію DLL використовувати, є частиною пекла DLL. Називайте це "пеклом залежностей", якщо ви хочете відрізнити від деяких старих ідіосинкратичних форм поведінки Windows. Незважаючи на це, за замовчуванням блокування виконуваних файлів не допомагає керувати спільними залежностями. Зовсім. Речі, які залежать від конкретного файлу, можуть навіть не працювати під час спроби його оновити; немає додаткової безпеки. Існує 2 варіанти спільних залежностей: безкоштовний для всіх, який ризикує зламатися при спробі запустити його, або менеджер пакунків, який заважає вам встановлювати речі.
jpmc26,

Це питання не стосується рішення, який EXE чи DLL використовувати взагалі, а стосується того, що відбувається за замовчуванням і чому. Ви обговорюєте зовсім іншу тему. Блокування використовується після прийняття рішення, який EXE або DLL виконати, щоб отримати певний рівень додаткового контролю першим користувачем, а саме Windows у цьому прикладі, та розповісти іншим про цей контроль. І не дозволяючи «іншим» видаляти чи писати у файли, якими Windows потребує чомусь, і тому блокує їх, звичайно, це механізм додаткової координації.
Торстен

1
Деякі файли EXE або DLL, швидше за все, "не в пам'яті", але за замовчуванням відображені в них. Для картографування необхідний доступ до вмісту файлу, тому довільна його заміна за замовчуванням вважається небезпечною, і слід знати, що робиш. Що очевидно не так, якщо хтось дивується заблокованим EXE або DLL. OTOH, всі інші файли заблоковані лише за замовчуванням, не обов'язково, тому програми можуть вирішувати, чи дозволяють вони вам писати чи видаляти операції, залежно від їх використання. Розробники додатків повинні краще за довільних користувачів знати, як вони використовують свої файли та які операції безпечні коли.
Торстен

0

Варіанти NT мають

openfiles

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

openfiles / local /?

розповідає, як це зробити, а також про те, що за це стягується штраф за виконання.


0

При запуску виконувані файли поступово відображаються в пам'яті. Це означає, що частини виконуваного файлу завантажуються за необхідності. Якщо файл буде замінено місцями перед нанесенням на карту всіх розділів, це може спричинити значну нестабільність.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.