실행 파일 잠금 : Windows는 그렇고 Linux는 그렇지 않습니다. 왜?


82

Windows (.exe 또는 .dll)에서 파일이 실행될 때 파일이 잠겨 삭제, 이동 또는 수정할 수 없음을 확인했습니다.

리눅스는, 다른 한편으로는, 파일을 실행 잠그지 않고 당신은 할 수 있습니다 , 삭제, 이동을하거나 수정합니다.

Linux가 작동하지 않는데 Windows가 잠기는 이유는 무엇입니까? 잠금에 이점이 있습니까?


6
주어진 파일을 잠그는 프로세스를 표시 할 수있는 탐색기의 상황에 맞는 메뉴에 메뉴 항목을 추가하는 WhoLockMe 라는 유틸리티 가 있습니다. 이상한 파일 잠금 오류가 발생할 때 매우 유용합니다. 편집 : 나는 이것이 질문에 대한 대답이 아니라는 것을 알고 있지만, (단순한 의견이 아닌) 별도의 답변을 보장하기에 충분한 맥락에서 유용하다고 생각했습니다.
JesperE

답변:


106

Linux에는 참조 횟수 메커니즘이 있으므로 실행하는 동안 파일을 삭제할 수 있으며 이전에 열었던 일부 프로세스에 열린 핸들이있는 한 계속 존재합니다. 파일을 삭제하면 해당 파일의 디렉토리 항목이 제거되므로 더 이상 열 수 없지만이 파일을 이미 사용중인 프로세스는 계속 사용할 수 있습니다. 이 파일을 사용하는 모든 프로세스가 종료되면 파일이 자동으로 삭제됩니다.

Windows에는이 기능이 없으므로 실행중인 모든 프로세스가 완료 될 때까지 파일을 강제로 잠급니다.

나는 Linux 동작이 바람직하다고 생각합니다. 아마도 몇 가지 깊은 구조적 이유가있을 수 있지만 제가 가장 매력적인 이유는 Windows에서 때때로 파일을 삭제할 수없고 이유를 알 수 없으며 일부 프로세스가 파일을 보관하고 있다는 것입니다. 사용하다. Linux에서는 결코 발생하지 않습니다.


2
Windows의 Process Explorer와 같은 도구를 사용하여 파일 / 폴더를 사용하는 프로세스를 확인할 수 있습니다.
J c

14
Linux 동작을 선호하는 실질적인 이유는 시스템이 실행되는 동안 시스템의 OS 및 기타 소프트웨어를 업데이트 할 수 있고 절대 / 거의 재부팅하지 않을 수 있다는 것입니다 (다시 부팅하지 않고 실행중인 커널을 전환 할 수도 있습니다. 가동 시간이 중요한 애플리케이션).
joelhardi

6
"Windows에는이 기능이 없습니다."... 확실합니까? NT 커널은 핸들과 참조가있는 refcounting 객체를 기반으로합니다.
Adam Mitz

10
Windows에는 실제로 파일이 열려있는 동안 다른 프로세스가 파일에 수행 할 수있는 작업을 정의 할 수있는 3 비트가 있습니다. FILE_SHARE_DELETE비트가 설정된 경우 파일이 열려있는 동안 파일을 삭제할 수 있습니다 . EXE와 DLL을로드하는 PE 로더가이 비트를 설정한다고 생각하지 않습니다. 핸들은 참조 횟수가 계산되고 삭제시 마지막 핸들이 삭제되면 파일이 사라집니다.하지만이 핸들과 Unix의 차이점은 NT가이 경우 동일한 이름으로 새 파일이 생성되는 것을 차단한다는 것입니다.
asveikau

2
comonad가 말하는 것은 완전히 잘못되었습니다. NTFS는 물론 Hardlinks를 사용하고 항상 그렇습니다. symlink는 Windows Vista에 추가되었습니다. Windows가 참조 copunting을 사용하지 않는다는 것은 완전히 잘못된 것입니다. 파일이 어떤 상황에서 삭제 가능한지 명확하게 말한 CreateFile과 같은 API를 읽습니다. 그리고 그것이 질문에 대한 실제 대답을위한 적절한 장소이기도합니다. CreateFile에는 열린 파일의 필수 잠금을 제어하고 응용 프로그램이 결정할 수 있도록하는 인수 claled dwShareMode가 있습니다. 기본값은 ... 배타적 잠금입니다
토르스텐 Schöning

29

내가 아는 한, 리눅스 실행 중일 때 실행 파일을 잠그지 만 inode를 잠급니다 . 즉, "파일"을 삭제할 수 있지만 inode는 파일 시스템에 그대로 남아 있으며 실제로 삭제 한 것은 링크뿐입니다.

유닉스 프로그램은 항상 파일 시스템에 대해 이런 식으로 생각하고 임시 파일을 만들고 열고 이름을 삭제합니다. 파일은 여전히 ​​존재하지만 다른 사람이 사용할 수 있도록 이름이 해제되어 다른 사람이 볼 수 없습니다.


"항상"? 어떤 예?
Mez

4
"유닉스 보안 임시 파일"에 대해 Google에 문의하면 해당 기술이 잘 알려져 있고 일반적으로 사용된다는 것을 보여줄 수있는 충분한 설명을 찾을 수 있습니다. 구체적인 예는 없지만 임시 파일을 사용하는 보안에 민감한 앱이이를 수행한다고 감히 말할 수 있습니다.
Dave Sherohman

26

Linux는 파일을 잠급니다. 실행중인 파일을 덮어 쓰려고하면 "ETXTBUSY"(텍스트 파일 사용 중)가 표시됩니다. 그러나 파일을 제거 할 수 있으며 커널은 파일에 대한 마지막 참조가 제거 될 때 파일을 삭제합니다. (시스템이 완전히 종료되지 않은 경우, 이러한 파일은 파일 시스템을 확인할 때 "Deleted inode has zero d-time"메시지의 원인이됩니다. 실행중인 프로세스에 참조가 있으므로 완전히 삭제되지 않은 것입니다. 지금은 그렇습니다.)

여기에는 몇 가지 주요 이점이 있습니다. 실행 파일을 삭제하고 교체 한 다음 프로세스를 다시 시작하여 실행중인 프로세스를 업그레이드 할 수 있습니다. init도 이와 같이 업그레이드 할 수 있고 실행 파일을 교체하고 신호를 보내면 재부팅 할 필요없이 자체적으로 re-exec ()됩니다. (이것은 일반적으로 업그레이드의 일부로 패키지 관리 시스템에서 자동으로 수행됩니다)

Windows에서는 사용중인 파일을 교체하는 것이 매우 번거로운 것처럼 보이며 일반적으로 실행중인 프로세스가 없는지 확인하려면 재부팅해야합니다.

매우 큰 로그 파일이 있고이를 제거하는 경우와 같은 몇 가지 문제가있을 수 있지만 해당 파일에 로깅하는 프로세스에 파일을 다시 열도록 알리는 것을 잊으면 참조가 유지 될 것입니다. 디스크가 갑자기 더 많은 여유 공간을 얻지 못한 이유.

Linux에서 임시 파일에 대해이 트릭을 사용할 수도 있습니다. 파일을 열고 삭제 한 다음 파일을 계속 사용하십시오. 프로세스가 종료되면 (어떠한 이유에 관계없이-정전이더라도) 파일이 삭제됩니다.

lsof 및 fuser와 같은 프로그램 (또는 / proc // fd에서 훑어보기)은 더 이상 이름이없는 파일이 열려있는 프로세스를 보여줄 수 있습니다.


6

나는 리눅스 / 유닉스가 처음부터 다중 사용자 시스템으로 구축 되었기 때문에 동일한 잠금 메커니즘을 사용하지 않는다고 생각합니다. 여러 사용자가 동일한 파일을 사용하거나 다른 목적으로도 사용할 가능성을 예상 할 수 있습니다.

잠금에 이점이 있습니까? 음, OS가 관리해야하는 포인터의 양을 줄일 수 있지만 이제는 절약되는 양이 매우 미미합니다. 잠금에 대해 제가 생각할 수있는 가장 큰 장점은 이것이 사용자가 볼 수있는 모호성을 줄이는 것입니다. 사용자 a가 바이너리 파일을 실행 중이고 사용자 b가이 파일을 삭제하면 실제 파일은 사용자 A의 프로세스가 완료 될 때까지 계속 남아 있어야합니다. 그러나 사용자 B 또는 다른 사용자가 파일 시스템에서 파일 시스템을 검색하면 찾을 수 없지만 계속 공간을 차지합니다. 나에게 큰 걱정거리는 아닙니다.

나는 대체로 윈도우의 파일 시스템과의 하위 호환성에 대한 질문이라고 생각합니다.


이 문맥에서 "Windows"는 Windows NT 라인입니다. 이것은 단일 사용자 Windows 3.11의 다중 사용자 후속 제품으로 설계되었습니다. Multics의 단일 사용자 후속 제품인 Unix와 비교하십시오.
MSalters

6

나는 당신이 Windows에 대해 너무 절대적이라고 생각합니다. 일반적으로 실행 파일의 코드 부분에 스왑 공간을 할당하지 않습니다. 대신 실행 파일 및 DLL에 대한 잠금을 유지합니다. 폐기 된 코드 페이지가 다시 필요한 경우 단순히 다시로드됩니다. 그러나 / SWAPRUN을 사용하면 이러한 페이지가 스왑 상태로 유지됩니다. CD 또는 네트워크 드라이브의 실행 파일에 사용됩니다. 따라서 Windows는 이러한 파일을 잠글 필요가 없습니다.

.NET의 경우 Shadow Copy를 살펴보십시오 .


1

파일에서 실행 된 코드를 잠 가야하는지 여부는 설계 결정이고 MS는 실제로는 분명한 이점이 있기 때문에 잠그기로 결정했습니다. 이렇게하면 어떤 버전의 코드가 어떤 응용 프로그램에서 사용되는지 알 필요가 없습니다. 이것은 대부분의 사람들이 무시하는 Linux 기본 동작의 주요 문제입니다. 시스템 전체 라이브러리가 교체되면 이러한 라이브러리의 코드를 사용하는 앱을 쉽게 알 수 없습니다. 대부분의 경우 패키지 관리자가 해당 라이브러리의 일부 사용자를 알고 다시 시작하는 것이 가장 좋습니다. 그러나 그것은 일반적으로 작동하며 Postgres 및 libs 등과 같은 것을 잘 알고 있습니다. 더 흥미로운 시나리오는 대부분의 경우 패키지 관리자가 단순히 앱을 알지 못하기 때문에 일부 타사 라이브러리에 대해 자체 애플리케이션을 개발하고 대체되는 경우입니다. 그리고 그 네이티브 C 코드 등의 문제 일뿐만 아니라 거의 모든 상황에서 발생할 수 있습니다. mod_perl과 함께 httpd를 사용하고 패키지 관리자를 사용하여 설치된 일부 Perl 라이브러리를 사용하고 어떤 이유로 든 패키지 관리자가 해당 Perl 라이브러리를 업데이트하도록합니다. 종속성을 알지 못하기 때문에 httpd를 다시 시작하지 않습니다. 이와 같은 예제가 많이 있습니다. 단순히 모든 파일이 런타임에 의해 메모리에서 사용중인 코드를 포함 할 수 있기 때문입니다. Java, Python 등을 생각하면됩니다.

따라서 기본적으로 파일을 잠그는 것이 좋은 선택 일 수 있다는 의견을 가질 수있는 좋은 이유가 있습니다. 하지만 그 이유에 동의 할 필요는 없습니다.

그래서 MS는 무엇을 했습니까? 그들은 단순히 파일을 잠 가야하는지 여부를 결정할 수있는 기회를 호출 응용 프로그램에 제공하는 API를 만들었지 만이 API의 기본값은 첫 번째 호출 응용 프로그램에 배타적 잠금을 제공하는 것이라고 결정했습니다. CreateFiledwShareMode인수 에 대한 API를 살펴보십시오 . 이것이 일부 응용 프로그램에서 사용중인 파일을 삭제할 수없는 이유입니다. 단순히 사용 사례를 신경 쓰지 않고 기본값을 사용했기 때문에 Windows에서 파일에 대해 독점 잠금을 얻었습니다.

Windows에 대해 말하는 사람들이 핸들에서 참조 계산을 사용하지 않거나 Hardlink 등을 지원하지 않는다고 말하는 사람들을 믿지 마십시오. 완전히 잘못된 것입니다. HANDLE을 사용하는 거의 모든 API는 참조 계산과 관련된 동작을 문서화하며, NTFS에 대한 거의 모든 기사에서 하드 링크를 지원하고 항상 지원한다는 것을 쉽게 읽을 수 있습니다. Windows Vista 이후로 Symlink에 대한 지원도 제공하고 있으며 다음에 대한 API를 제공하여 Hardlink에 대한 지원이 향상되었습니다. 하며 지정된 파일 등에 대한 모두 읽을 .

또한, Ext4 에서 파일을 설명하는 데 사용되는 구조를 간단히 살펴보고 싶을 수도 있습니다. 예를 들어 많은 공통점이있는 NTFS 와 비교하면됩니다 . 둘 다 파일 이름과 같은 속성에서 데이터를 분리하는 익스텐트 개념으로 작동하며 inode는 이전에 대한 또 다른 이름이지만 유사한 개념입니다. Wikipedia조차도 기사 에 두 파일 시스템을 모두 나열합니다. .

조각 모음과 마찬가지로 인터넷의 다른 OS에 비해 Windows의 파일 잠금에 대한 FUD가 많이 있습니다. 이 FUD 중 일부는 Wikipedia 에서 간단히 읽을 수 있습니다 .


공유 종속성의 버전 관리에 대한 소란 스러움은 관련이 없습니다. 업데이트가 재부팅이 필요한 경우에도 이러한 문제를 처리해야합니다. Windows에서는 이름이 DLL hell입니다. 더욱이, 당신이 설명하는 런타임 동작은 이미 파일이 메모리에로드되어 있고 계속 사용할 수있는 Linux의 경우에 의해 완전히 처리됩니다. 응용 프로그램은 Windows가 파일 잠금을 해제하기 위해 강제로 재부팅 할 때와 마찬가지로 다시 시작할 때까지 이전 버전으로 계속 실행됩니다. 그면에는 이점이 없습니다.
jpmc26

DLL 지옥은 물론 요점을 완전히 놓치고 있으며 우리는 더 이상 90 년대를 가지고 있지 않습니다 WinSxS. 또한 메모리에 물건을로드하고 보관하는 것이 아니라 필요한 경우 Windows도 정확히 수행합니다. 파일을 교체해야하는지 여부를 파악하고 결정하는 책임이 누구인지 결정하는 것입니다. Windows-API를 사용하면 파일의 첫 번째 사용자가 결정을 내릴 수 있습니다.
Thorsten Schöning 19 년

하지만 그게 내 요점입니다. 사용할 DLL 버전을 결정하는 것은 DLL 지옥의 일부입니다. Windows의 오래된 특이한 동작과 구별하려면 "종속성 지옥"이라고 부르십시오. 어쨌든 실행 파일 잠금을 기본값으로 설정해도 공유 종속성 관리에 도움이되지 않습니다 . 조금도. 특정 파일에 의존하는 것은 업그레이드를 시도 할 때 실행되지 않을 수도 있습니다. 추가 안전이 없습니다. 공유 종속성에는 두 가지 선택이 있습니다. 모두에게 무료 (실행하려고 할 때 물건이 깨질 위험이 있음) 또는 패키지 관리자가 물건을 설치하지 못하게 할 위험이 있습니다.
jpmc26

이 질문은 사용할 EXE 또는 DLL을 결정하는 것이 아니라 나중에 기본적으로 발생하는 일과 이유에 대한 것입니다. 당신은 완전히 다른 주제를 논의하고 있습니다. 잠금은 실행될 EXE 또는 DLL을 결정한 후에 사용되어 첫 번째 사용자 (이 예에서는 Windows 자체)가 일정 수준의 추가 제어를 얻고 해당 제어에 대해 다른 사용자에게 알립니다. 그리고 "다른 사용자"가 어떤 이유로 Windows에 필요한 파일을 삭제하거나 기록하지 못하도록하여 파일을 잠그는 것은 물론 추가 조정을위한 메커니즘입니다.
Thorsten Schöning

1
어쨌든 일부 EXE 또는 DLL은 "메모리에"있지 않지만 기본적으로 매핑됩니다. 매핑을 위해서는 파일 내용을 사용할 수 있어야하므로 임의로 교체하는 것은 기본적으로 안전하지 않은 것으로 간주되며 무엇을하는지 알아야합니다. 잠긴 EXE 또는 DLL에 놀라는 경우에는 분명히 그렇지 않습니다. OTOH, 다른 모든 파일은 기본적으로 만 잠겨 있으며 반드시 그런 것은 아니므로 앱은 사용 사례에 따라 작업을 작성하거나 삭제할 수 있는지 여부를 결정할 수 있습니다. 앱 개발자는 임의의 사용자보다 파일을 사용하는 방법과 어떤 작업이 언제 안전한지 더 잘 알아야합니다.
Thorsten Schöning

0

NT 변종에는

열린 파일

명령은 어떤 프로세스가 어떤 파일에 대해 핸들을 가지고 있는지 보여줍니다. 그러나 시스템 전역 플래그 '객체 목록 유지'를 활성화해야합니다.

openfiles / 로컬 /?

이를 수행하는 방법과이를 수행하면 성능 저하가 발생 함을 알려줍니다.


0

실행 파일은 실행시 점진적으로 메모리에 매핑됩니다. 이는 실행 파일의 일부가 필요에 따라로드된다는 것을 의미합니다. 모든 섹션이 매핑되기 전에 파일이 스왑 아웃되면 심각한 불안정이 발생할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.