동일한 디렉토리에 있는 파일에만 해당됩니다.

동일한 디렉토리에 있는 파일에만 해당됩니다.

Linux에서는 openatsyscall을 사용하여 파일을 생성하고 파일 존재 여부를 테스트할 수 있습니다. C/C++ 메모리 모델 측면에서 말하면, 파일을 생성하고 그 존재를 확인하면 동기화 관계가 생성됩니다. 내가 알아야 할 것은 이러한 동기화가 모두 순차적으로 서로 일치하는지 여부입니다. (확실히 그러기를 바라지만, 실제로 이 내용이 어디에서도 문서화되어 있는 것을 본 적이 없습니다.)

예를 들어, 프로세스 p1과 p2, 경로 A와 B가 있다고 가정해 보겠습니다.

p1이 다음을 수행하는 경우: 생성(A), 그런 다음 생성(B)

그리고 p2는 다음을 수행합니다. B를 열려고 시도한 다음 A를 열려고 시도합니다.

다른 프로세스가 A나 B를 방해하지 않는 경우, p2가 B를 성공적으로 열었지만 A를 찾지 못하는 것이 가능합니까?

차이점이 있다면 모든 작업이 하나의 파일 시스템 내에 있다고 가정할 수 있습니다.

답변1

모든 기본 디스크 및 멀티 코어 CPU 최적화를 통해 두 프로세스 간의 작업 시퀀스의 엄격한 순서를 결정하는 것이 반드시 가능한 것은 아닙니다. 이것이 시간 의존적 동작의 가능성이 있는 경우 세마포어를 사용하는 이유입니다.

답변2

동일한 디렉토리에 있는 파일에만 해당됩니다.

6가지 규칙이 있습니다:

  1. 읽기 액세스. 잠금 규칙: 호출자는 우리가 액세스하는 디렉터리를 잠급니다. 잠금은 공유됩니다.

  2. 객체 생성. 잠금 규칙: 위와 동일하지만 잠금은 배타적입니다.

  3. 물체 제거. 잠금 규칙: 호출자는 부모를 잠그고, 피해자를 찾고, 피해자를 잠그고 메서드를 호출합니다. 자물쇠는 독점적입니다.

  4. rename()그건~ 아니다크로스 디렉토리. 잠금 규칙: 호출자는 상위 항목을 잠그고 소스와 대상을 찾습니다. 교환의 경우( RENAME_EXCHANGE플래그 인수 사용) 둘 다 잠급니다. 어쨌든 대상이 이미 존재하는 경우 잠급니다. 소스가 디렉터리가 아닌 경우 잠급니다. 둘 다 잠그려면 inode 포인터 순서로 잠그십시오. 그런 다음 메서드를 호출합니다. 모든 자물쇠는 배타적입니다. 주의: 공유된 소스(및 교환의 경우 대상)를 잠그지 않고도 벗어날 수 있습니다.

  5. 링크 생성. 잠금 규칙:

    • 부모 잠금

    • 소스가 디렉토리가 아닌지 확인하십시오

    • 잠금 소스

    • 메소드를 호출하십시오. 모든 자물쇠는 배타적입니다.

  6. 디렉토리 간 이름 바꾸기. 전체에서 가장 까다롭습니다. 잠금 규칙:

    • 파일 시스템을 잠그다

    • 부모를 "조상 먼저" 순서로 잠급니다.

    • 소스와 타겟을 찾아보세요.

    • 이전 부모가 대상과 같거나 대상의 자손인 경우 -로 실패합니다.ENOTEMPTY

    • 새 부모가 소스와 같거나 소스의 하위인 경우 -로 실패합니다.ELOOP

    • 교환인 경우 소스와 대상을 모두 잠급니다.

    • 대상이 있으면 잠급니다. 소스가 디렉터리가 아닌 경우 잠급니다. 둘 다 잠그려면 inode 포인터 순서대로 잠그십시오.

    • 메소드를 호출하십시오. 모두 ->i_rwsem독점적으로 사용됩니다. 다시 말하지만, 공유된 소스(및 교환의 경우 대상)를 잠그는 것으로 벗어날 수 있습니다.

위의 규칙은 메소드에 의해 읽혀지거나 수정되거나 제거될 모든 디렉토리가 호출자에 의해 잠기도록 보장합니다.

잠금은 선형성을 강화하므로 작업이단일 디렉토리에완전히 주문되었습니다. 그러나 읽기 액세스(1), 개체 생성(2) 및 개체 제거(3)는 디렉터리 잠금보다 더 넓은 잠금을 사용하지 않으므로 다른 디렉터리에서 디렉터리 작업의 순서가 보장되지 않습니다. 다른 관찰자는 다른 방식으로 인터리브된 디렉토리의 선형 기록을 볼 수 있습니다.

관련 정보