NodeJS 파일 잠금 심층 연구

저는 평면 디자이너와 2D/3D 아티스트를 위해 버전 제어 소프트웨어를 개발했는데 Angular and Electron에서 Snowtrack이라고 합니다.이 블로그 글에서 저는 Snowtrack 개발 과정에서 겪은 파일 잠금에 관한 기술적 도전을 소개할 것입니다.

스키 코스는 무엇입니까?


Snowtrack은 직관적이고 사용하기 쉬우며 초고속 그래픽 프로젝트 버전 제어 소프트웨어다.평면 디자이너와 2D/3D 아티스트가 비기술 워크플로우를 통해 버전 제어에 액세스할 수 있도록 하는 것이 목적입니다.
스키 코스 사용자 인터페이스에 대한 자세한 내용은 다음 화면 캡처를 참조하십시오.

제가 예전에 지었어요.


UI 애플리케이션의 경우 각도와 전자의 조합을 사용했습니다.베이스 버전 제어 엔진의 이름은 SnowFS입니다. 이것은 제가 개발한 소스 프로젝트입니다. Git와 Git LFS의 신속하고 간단한 대체 방안입니다.GitHub으로 문의하신 것을 환영합니다.몇 달 전에, 나는 dev.to에 그것에 관한 블로그 글을 한 편 썼다.

기술 과제1


그래픽 항목의 크기에 큰 차이가 있을 수 있습니다.단일 Photoshop 파일에서 50GB의 3D 장면, 텍스쳐 및 리소스 파일 세트로 이동합니다.이들 항목의 유형은 모두 자신의 문제가 있다.다음은 파일 잠금에 대한 오해를 해명하고 싶습니다.

파일 잠금


다음 코드 세션을 보십시오.
// Process 1
fd = fs.openSync("~/foo", "w");

// Process 2
fd = fs.openSync("~/foo", "w");
여러 프로세스가 같은 파일을 동시에 열려고 한다고 상상해 보세요.너는 무슨 일이 발생할 것이라고 생각하니?
답: 이것은 운영체제, 그리고 당신이 모든 절차의 관리자인지에 달려 있습니다.fs.openSync을 호출하면 NodeJS는 this C code에서 본 것처럼 OS 함수로 호출됩니다.
static ssize_t uv__fs_open(uv_fs_t* req) {
  return open(req->path, req->flags | O_CLOEXEC, req->mode);
}
함수 open(..)은 모든 운영체제에서 사용할 수 있는 운영체제 함수이다.그러나 이 함수의 내부 구조는 윈도, 리눅스, 맥OS 사이에 다르기 때문에 각각 소개할 것이다.

macOS/Linux


기술적으로 말하자면 맥OS와 리눅스에는 진정한 파일 잠금 메커니즘이 없다. fcntl 이라는 함수로 잠금 파일을 읽거나 쓸 수 있지만, 이 함수를 사용하는 프로그램만 파일 잠금을 고려하고 준수합니다.이것은 fcntl을 사용하지 않고 파일을 열려는 다른 모든 프로세스가 파일 권한이 허락된다면 파일 핸들을 가져와 내용을 조작할 수 있다는 것을 의미한다.아뿔싸.
이것이 바로 맥OS와 리눅스의 파일 잠금도 "advisory file locking"이라고 하는 이유다.

창문.


Windows는 더 복잡합니다.Windows는 두 개의 파일 열기 기능을 제공합니다.또는 CreateFile이라는 Windows API 함수를 통해(예, 이것은 파일을 여는 이름이 맞습니다.)
...또는 open(..) 을 통해그러나 Windows의 open(..) 함수는 POSIX 확장이며 내부에서도 CreateFile을 사용합니다.
위에서 보듯이 NodeJS는 open(..)을 사용하지만 이것은 CreateFile의 포장기일 뿐이라는 것을 알고 있기 때문에 이 함수를 검사해 보겠습니다.
// The low-level open function of Windows.
HANDLE CreateFile(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);
CreateFile에는 dwShareMode이라는 매개 변수가 있다.dwShareMode=0으로 열린 파일은 핸들이 닫히기 전에 다시 열 수 없습니다.
따라서 한 파일에 open(..)을 사용하고 다른 프로세스에서 CreateFile(…, dwShareMode=0)을 사용하여 파일을 연 경우 다음 오류 메시지가 표시됩니다.

The process cannot access the file because it is being used by another process


한편, NodeJS에서 fs.openSync을 사용하거나 C/C++에서 open(..)을 사용하여 아직 열리지 않은 파일을 열면 다른 프로그램이 수정하는 것을 막을 수 없습니다.*
* 파일 권한을 해결 방법으로 사용하지 않는 한 진정한 파일 잠금은 아닙니다.
이를 증명하기 위해, POSIX 표준에 부합되는 읽기/쓰기 공유 로고를 사용하여 fs.openSync을 실행하는 것을 보실 수 있습니다.

이는 Windows에서 CreateFile을 사용하지 않으면 다른 응용 프로그램에서 파일을 열고 수정하는 것을 막을 수 없다는 것을 의미합니다.

이것은 스키장과 무슨 관계가 있습니까?


사용자가 도면 응용 프로그램에 큰 파일을 저장하고 디스크에 파일이 기록되어 있을 때 파일 변경 사항을 제출하려고 시도할 때 상상해 보십시오.Snowtrack은 어떻게 처리합니까?CreateFile은 파일 잠금이 없고 대부분의 응용 프로그램은 파일 프로토콜을 따르지 않기 때문에 Snowtrack은 포토샵, Blender,co. 파일을 어떻게 열고 쓰는지 제어할 수 없다고 한다.
이것은 파일을 다른 프로세스에서 썼는지 검사하는 유일한 확실한 기회는 제출하기 전에 시스템의 모든 프로세스가 이 파일에 쓰기 핸들을 가지고 있는지 검사하는 것이다.
  • 은 Windows에서 교체할 파일이 더 이상 열리지 않도록 프로그램을 설치하는 데 주로 사용되는 사용자 정의 도움말 프로그램과 Restart Manager의 Windows API로 이 문제를 해결했습니다.
  • MacOS의
  • I에서 시스템 프로세스 open(..) (열린 파일 나열)을 호출하고 작업 디렉토리를 포함하여 명령 실행을 가속화합니다.
  • 또 뭐 있어요?


    Snowtrack의 개발은 수많은 기술적 도전을 가져왔고 저는 더 많은 견해를 공유하고 싶습니다.
    파일 잠금, 전자/각도 경쟁 조건, I/O 포화, 서버 구축, 업데이트 메커니즘, 에지 상황.이 프로젝트가 있어서 저는 많은 주제를 접했습니다. 만약 당신이 흥미가 있다면 저는 후속 블로그 글을 기꺼이 쓰겠습니다.아래의 평론에서 저에게 알려주세요.
    만약 당신이 SnowFS, Snowtrack 또는 나를 지원하고 싶다면, 나의 대열에 가입하는 것을 환영합니다.
    읽어주셔서 감사합니다. -)

    TLDR


    파일 잠금 시작하게 하지 마.

    부록: Windows에서 사용 중인 파일 대화 상자는 어떻습니까?


    Windows 사용자인 경우 이전에 이 오류 메시지를 보았을 수 있습니다.

    HFS는 다른 Windows 시스템에 비해 매우 다릅니다.
    NTFS에는 inode와 같은 파일이 없습니다. 따라서 삭제된 파일의 마지막 파일 핸들을 닫으면 스팸 수집은 이 파일을 삭제하지 않습니다.'사용 중인 파일' 대화상자는 프로세스가 지정한 파일에 파일 핸들을 가지고 있으면 (어떻게 열든지) 이름을 바꾸거나 이동하거나 삭제할 수 없습니다.이것은 파일 내용에 대한 파일 잠금을 의미하지 않습니다.

    좋은 웹페이지 즐겨찾기