QLockFile Class
QLockFile 클래스는 파일을 사용하여 프로세스 간에 잠금 기능을 제공합니다. 더 보기...
| 헤더: | #include <QLockFile> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
- 상속된 멤버를 포함한 모든 멤버 목록
- QLockFile은 입출력 및 네트워킹의 일부입니다.
공개 유형
| enum | LockError { NoError, LockFailedError, PermissionError, UnknownError } |
공개 함수
| QLockFile(const QString &fileName) | |
| ~QLockFile() | |
| QLockFile::LockError | error() const |
| QString | fileName() const |
| bool | getLockInfo(qint64 *pid, QString *hostname, QString *appname) const |
| bool | isLocked() const |
| bool | lock() |
| bool | removeStaleLockFile() |
| void | setStaleLockTime(int staleLockTime) |
(since 6.2) void | setStaleLockTime(std::chrono::milliseconds staleLockTime) |
| int | staleLockTime() const |
(since 6.2) std::chrono::milliseconds | staleLockTimeAsDuration() const |
| bool | tryLock(int timeout) |
(since 6.2) bool | tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero()) |
| void | unlock() |
상세 설명
잠금 파일을 사용하면 여러 프로세스가 동일한 리소스에 동시에 액세스하는 것을 방지할 수 있습니다. 예를 들어, 디스크의 구성 파일이나 소켓, 포트, 공유 메모리 영역 등이 있습니다...
공유 리소스에 액세스하는 모든 프로세스가 동일한 파일 경로의 QLockFile을 사용하는 경우에만 직렬화가 보장됩니다.
QLockFile은 두 가지 사용 사례를 지원합니다. 하나는 단기 작업(예: 새 설정을 저장하기 전에 구성 파일이 변경되었는지 확인)을 위해 리소스를 보호하는 것이고, 다른 하나는 불특정 기간 동안 리소스(예: 사용자가 편집기에서 연 문서)를 장기적으로 보호하는 것입니다.
단기 작업을 위해 자원을 보호할 때는 ` lock()`를 호출하고 실행 중인 작업이 모두 완료될 때까지 기다리는 것이 허용됩니다. 그러나 장기간에 걸쳐 자원을 보호할 때는, 자원이 잠겨 있음을 사용자에게 알리기 위해 애플리케이션이 항상 ` setStaleLockTime(0ms)`를 호출한 다음, 짧은 타임아웃을 설정하여 ` tryLock()`를 호출해야 합니다.
잠금을 보유한 프로세스가 중단되면, 잠금 파일은 디스크에 남아 다른 어떤 프로세스도 공유 리소스에 영구적으로 접근하지 못하게 할 수 있습니다. 이러한 이유로 QLockFile은 파일에 기록된 프로세스 ID를 기반으로 이러한 "오래된" 잠금 파일을 감지하려고 시도합니다. 그 사이 프로세스 ID가 재사용된 상황을 대비하기 위해, 현재 프로세스 이름을 잠금 파일의 프로세스 ID에 해당하는 프로세스 이름과 비교합니다. 프로세스 이름이 다르면 잠금 파일은 오래된 것으로 간주됩니다. 또한, 잠금 파일의 마지막 수정 시간(단기 작업 사용 사례를 위해 기본값은 30초)도 고려됩니다. 잠금 파일이 오래된 것으로 판명되면 삭제됩니다.
따라서 장기간에 걸쳐 리소스를 보호해야 하는 사용 사례의 경우, ` setStaleLockTime(0)`을 호출해야 하며, ` tryLock()`가 ` LockFailedError`를 반환하면, 필요에 따라 ` getLockInfo()`를 사용하여 더 자세한 정보를 제공하면서 사용자에게 문서가 잠겨 있음을 알려야 합니다.
제한 사항
QLockFile의 구현은 대부분의 환경과 파일 시스템에서 일반적으로 안전합니다. 그러나 잠금 파일이 실제로는 유효함에도 불구하고 유효하지 않다고 잘못 판단하거나, 유효하지 않은 파일을 감지하지 못하거나, 잠금 과정에서 경합이 발생하는 몇 가지 상황이 있습니다. 이 섹션에서는 이러한 문제들을 설명합니다.
이를 완화하기 위한 두 가지 주요 전략이 있습니다. 하나는 적절한 0이 아닌 값을 가진 ` staleLockTime()`를 선택하는 것이고, 다른 하나는 잠금 파일을 저장할 때 일반 로컬 파일 시스템을 선택하는 것입니다(예: 유닉스 시스템에서 루트로 실행 중인 경우 ` /var/lock ` 또는 ` runtime location`). QLockFile의 특정 사용 사례에서는 이러한 방법이 불가능할 수 있습니다. 예를 들어, QLockFile을 사용하여 사용자가 지정한 파일 경로가 편집 중임을 나타내는 경우 등이 있습니다.
비영구적인 머신 ID
QLockFile은 시스템 고유의 ID를 사용하여 현재 시스템의 잠금과 다른 호스트에서 실행되는 프로세스의 잠금을 구분합니다. 시간의 경과에 따라 머신 ID가 변경되는 경우(예: 부팅할 때마다 새로운 ID를 생성해야 하는 일시적 저장소를 사용하는 시스템), QLockFile은 재부팅 후 잠금 파일이 오래된 것임을 감지할 수 없습니다.
반대로, 두 대의 서로 다른 컴퓨터가 충돌하는 컴퓨터 ID를 가지고 있고(예: 복제된 시스템 이미지 또는 백업에서 복원된 경우) QLockFile에 네트워크 경로를 제공하는 경우, 이 클래스는 실제로는 유효한 잠금임에도 불구하고 잠금이 만료된 것으로 판단할 수 있습니다.
네이티브 잠금 기능의 부재
QLockFile은 ` staleLockTime()` 설정 이후에도 잠금이 유효(오래된 것이 아님)함을 다른 프로세스 및 스레드에 알리기 위해 운영 체제별 호출을 사용합니다. 이 기능은 일부 네트워크 기반 또는 가상 파일 시스템(예: Linux 및 macOS의 FUSE)에 있는 파일의 경우, 동일한 파일에 액세스할 때 서로 다른 파일 시스템을 사용하여 네이티브 잠금이 전달되지 않는 경우, 또는 필요한 시스템 호출을 차단하는 특정 환경에서는 지원되지 않을 수 있습니다.
네이티브 잠금 지원이 없는 경우, QLockFile은 잠금 파일 자체의 존재 여부, 수정 시간 및 내용에만 전적으로 의존합니다. 이 경우, 현재 리소스를 잠그고 있는 프로세스가 staleLockTime() 시간 이후에도 리소스를 계속 잡고 있으면, QLockFile이 잠금을 빼앗습니다.
네트워크 파일 시스템
네트워크 환경에서 네이티브 파일 잠금이 지원되는지 여부는 명시되지 않았습니다. 일부 구현에서는 파일 시스템에 액세스하는 모든 클라이언트에 대해 지원되기도 하고, 다른 구현에서는 로컬 시스템이 자체 프로세스에 대한 잠금을 지원하지만 네트워크를 통해 잠금을 공유하지 않기도 하며, 또 다른 구현에서는 단일 호스트 내부에서도 네이티브 잠금 기능이 아예 없을 수 있습니다. 또한, 동일한 파일에 대해 일부 클라이언트는 네트워크 잠금에 참여하고 다른 클라이언트는 참여하지 않을 수도 있습니다. 네트워크를 통해 잠금이 지원되지 않는 경우, QLockFile은 네이티브 잠금이 없는 경우에 대해 위에서 설명한 제한 사항을 따릅니다.
또한, 잠금 파일에 다른 호스트의 식별 정보가 포함되어 있는 경우, QLockFile은 잠금을 보유한 프로세스가 여전히 실행 중인지 확인할 수 없으며, 비정상 종료로부터 복구하기 위해 ` staleLockTime()`를 기다려야 합니다.
동일한 경로를 통해 서로 다른 실제 파일에 접근하기
두 프로세스가 파일 시스템에 대해 서로 다른 뷰를 가질 수 있으며, 이로 인해 동일한 파일 경로가 파일 시스템 내에서 서로 다른 파일이 될 수 있습니다. 이 경우 두 QLockFile 객체는 잠금 생성에 성공할 가능성이 높지만, 상호 배타적이지는 않을 것입니다. 잠금 파일이 보호하는 리소스가 두 프로세스 간에 여전히 공유되고 있다면, 이로 인해 충돌이 발생할 수 있습니다.
이러한 상황은 컨테이너(아래 참조)에서 가장 흔히 발생하지만, 컨테이너에만 국한된 것은 아닙니다.
컨테이너와 공유되는 파일
일부 컨테이너 구현에서는 특정 프로세스의 존재를 숨길 수 있습니다(예: 리눅스의 “PID 네임스페이스” 기능). 프로세스가 이러한 컨테이너 내에서 실행되고 있지만 호스트 시스템이나 다른 컨테이너와 머신 ID를 공유하는 경우, 서로 다른 컨테이너(또는 호스트)에 있는 두 프로세스는 잠금 프로세스가 여전히 실행 중인지 여부에 대해 잘못된 판단을 내리게 됩니다. 또한, 일부 컨테이너 컨트롤러는 컨테이너 내부의 부트 ID를 대체할 수 있으며, 이로 인해 시작된 프로세스는 타임스탬프가 아무리 최신 상태라 하더라도 잠금 파일이 항상 오래된 것이라고 판단하게 됩니다.
다른 일부 구현에서는, 컨테이너가 일시적인 저장소를 갖거나 충돌을 피하기 위해 의도적으로 새로운 머신 ID를 생성할 수도 있습니다. 이 경우, 애플리케이션은 비영구적인 머신 ID와 관련하여 위에서 설명한 문제를 겪게 됩니다.
그러나 네이티브 파일 잠금은 일반적으로 정상적으로 작동하므로(앞서 설명한 파일 시스템 및 환경적 제약 사항에 따라 다름), QLockFile이 파일이 갱신되지 않은 것으로 판단하더라도 네이티브로 잠겨 있는 잠금 파일은 가로채지 않습니다.
동일한 프로토콜을 사용하지 않는 액세스
QLockFile은 이 클래스가 구현한 프로토콜 외부에서 수행된 잠금 파일 수정 사항과는 상호 운용될 수 없습니다. 여기에는 tmpwatch 및 이와 유사한 다른 도구뿐만 아니라, 일부 바이러스 검사 도구나 유사한 도구에 의한 잠금 파일 제거도 포함됩니다.
시계 편차
QLockFile은 잠금 파일의 타임스탬프가 정확하다는 전제 하에 작동합니다. 시계가 앞으로 건너뛰면, QLockFile은 실제로는 그렇지 않은데도 잠금 파일이 오래된 것으로 판단할 수 있으며, 반대로 시계가 뒤로 건너뛸 경우에도 마찬가지입니다.
이러한 이유로, 모든 시스템은 네트워크를 통해 시간을 동기화하고 부팅 과정 초기에 이 동기화를 수행할 것을 권장합니다. 이는 특히 네트워크 파일 시스템의 경우 매우 중요합니다.
멤버 유형 문서
enum QLockFile::LockError
이 열거형은 lock() 또는 tryLock()의 마지막 호출 결과를 나타냅니다.
| 상수 | 값 | 상수값 |
|---|---|---|
QLockFile::NoError | 0 | 잠금이 성공적으로 획득되었습니다. |
QLockFile::LockFailedError | 1 | 다른 프로세스가 잠금을 보유하고 있어 잠금을 획득할 수 없었습니다. |
QLockFile::PermissionError | 2 | 상위 디렉터리에 대한 권한이 부족하여 잠금 파일을 생성할 수 없습니다. |
QLockFile::UnknownError | 3 | 다른 오류가 발생했습니다(예: 파티션이 가득 차서 잠금 파일을 쓸 수 없음). |
멤버 함수 문서
[explicit] QLockFile::QLockFile(const QString &fileName)
새로운 잠금 파일 객체를 생성합니다. 이 객체는 잠금 해제된 상태로 생성됩니다. ` lock()` 또는 ` tryLock()`를 호출하면, ` fileName `이라는 이름의 잠금 파일이 아직 존재하지 않을 경우 생성됩니다.
[noexcept] QLockFile::~QLockFile()
잠금 파일 객체를 삭제합니다. 잠금이 획득된 상태라면, 이 메서드는 잠금 파일을 삭제하여 잠금을 해제합니다.
QLockFile::LockError QLockFile::error() const
잠금 파일의 오류 상태를 반환합니다.
tryLock()가 false 를 반환하는 경우, 이 함수를 호출하여 잠금 실패의 원인을 확인할 수 있습니다.
QString QLockFile::fileName() const
잠금 파일의 파일 이름을 반환합니다.
bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname) const
잠금 파일의 현재 소유자에 대한 정보를 가져옵니다.
tryLock()가 false 를 반환하고, error()가 LockFailedError 를 반환하는 경우, 이 함수를 호출하여 기존 잠금 파일에 대한 추가 정보를 확인할 수 있습니다:
- 애플리케이션의 PID ( pid 에서 반환됨)
- 해당 애플리케이션이 실행 중인 hostname (네트워크 파일 시스템의 경우 유용함),
- 해당 파일을 생성한 애플리케이션의 이름( appname 에서 반환됨),
tryLock()는 해당 PID를 가진 실행 중인 애플리케이션이 없으면 파일을 자동으로 삭제하므로, LockFailedError 는 해당 PID를 가진 애플리케이션이 있을 때만 호출될 수 있습니다(비록 관련이 없을 수도 있지만).
이를 통해 사용자에게 기존 잠금 파일의 존재를 알리고, 파일을 삭제할지 여부를 선택할 수 있도록 할 수 있습니다. removeStaleLockFile()를 사용하여 파일을 제거한 후, 애플리케이션은 tryLock()를 다시 호출할 수 있습니다.
이 함수는 정보를 성공적으로 가져올 수 있으면 true 를 반환하고, 잠금 파일이 존재하지 않거나 예상된 데이터를 포함하지 않으면 false를 반환합니다. 이는 tryLock() 호출이 실패한 시점과 이 함수를 호출하는 시점 사이에 잠금 파일이 삭제된 경우에 발생할 수 있습니다. 이 경우 tryLock()를 다시 호출하기만 하면 됩니다.
bool QLockFile::isLocked() const
이 QLockFile 인스턴스가 잠금을 획득한 경우 true 을 반환하고, 그렇지 않은 경우 false 을 반환합니다.
lock(), unlock(), tryLock()도 참조하십시오 .
bool QLockFile::lock()
잠금 파일을 생성합니다.
다른 프로세스(또는 다른 스레드)가 이미 잠금 파일을 생성한 경우, 이 함수는 해당 프로세스(또는 스레드)가 잠금을 해제할 때까지 차단됩니다.
먼저 잠금을 해제하지 않고 동일한 스레드에서 동일한 잠금에 대해 이 함수를 여러 번 호출하는 것은 허용되지 않습니다. 파일이 재귀적으로 잠겨 있는 경우 이 함수는 데드락 상태에 빠집니다.
잠금이 획득된 경우 ` true `를 반환하고, 상위 디렉터리에 권한이 없는 등 복구 불가능한 오류로 인해 잠금을 획득할 수 없는 경우 `false`를 반환합니다.
unlock() 및 tryLock()도 참조하십시오 .
bool QLockFile::removeStaleLockFile()
기존 잠금 파일을 강제로 제거하려는 시도입니다.
단기적인 작업을 보호할 때는 이 함수를 호출하지 않는 것이 좋습니다. ` QLockFile ` 함수는 이미 ` staleLockTime()`보다 오래된 잠금 파일을 자동으로 제거해 주기 때문입니다.
이 메서드는 리소스를 장기간 보호하는 경우, 즉 ` staleLockTime(0)`을 사용하는 경우에만 호출해야 하며, ` tryLock()`가 ` LockFailedError`를 반환한 후 사용자가 잠금 파일 제거에 동의한 경우에 한해 호출해야 합니다.
성공 시 true 를 반환하고, 잠금 파일을 제거할 수 없는 경우 false를 반환합니다. 이는 Windows에서 잠금을 소유한 애플리케이션이 여전히 실행 중일 때 발생합니다.
void QLockFile::setStaleLockTime(int staleLockTime)
staleLockTime 를 잠금 파일이 유효하지 않은 것으로 간주되기까지의 시간(밀리초 단위)으로 설정합니다. 기본값은 30000, 즉 30초입니다. 애플리케이션에서 일반적으로 파일을 30초 이상 잠그고 있는 경우(예: 2분 동안 메가바이트 단위의 데이터를 저장하는 경우), setStaleLockTime()을 사용하여 더 큰 값을 설정해야 합니다.
staleLockTime 의 값은 lock() 및 tryLock()에서 기존 잠금 파일이 언제 '유효 기간이 만료된' 것으로 간주될지, 즉 중단된 프로세스에 의해 남겨진 것으로 간주될지를 결정하는 데 사용됩니다. 이는 그 사이 PID가 재사용된 경우에 유용하며, 따라서 유효 기간이 만료된 잠금 파일을 감지하는 한 가지 방법은 해당 파일이 오랫동안 존재해 왔다는 사실입니다.
이 함수는 오버로드된 함수로, 다음 호출과 동일합니다:
setStaleLockTime(std::chrono::milliseconds{staleLockTime});staleLockTime()도 참조하십시오 .
[since 6.2] void QLockFile::setStaleLockTime(std::chrono::milliseconds staleLockTime)
잠금 파일이 유효하지 않은 것으로 간주되는 간격을 ` staleLockTime`로 설정합니다. 기본값은 30초입니다.
애플리케이션이 일반적으로 30초 이상 파일을 잠그고 있는 경우(예: 2분 동안 메가바이트 단위의 데이터를 저장하는 경우), setStaleLockTime()을 사용하여 더 큰 값을 설정해야 합니다.
staleLockTime()의 값은 lock() 및 tryLock()에서 기존 잠금 파일이 언제 유효하지 않은 것으로 간주될지(즉, 중단된 프로세스가 남긴 잔여물인지) 판단하는 데 사용됩니다. 이는 그 사이 PID가 재사용된 경우에 유용하며, 유효하지 않은 잠금 파일을 탐지하는 한 가지 방법은 파일이 오랫동안 존재해 왔다는 사실입니다.
이 값을 0 또는 음수로 설정하면 잠금 파일의 타임스탬프 검증이 비활성화됩니다. QLockFile 는 파일 내용이 잠금을 설정했던 프로세스가 더 이상 실행 중이지 않음을 나타내는 경우, 여전히 오래된 잠금 파일을 감지합니다.
이 함수는 Qt 6.2에서 도입되었습니다.
staleLockTime()도 참조하십시오 .
int QLockFile::staleLockTime() const
잠금 파일이 더 이상 유효하지 않은 것으로 간주되기까지의 시간을 밀리초 단위로 반환합니다.
setStaleLockTime()도 참조하십시오 .
[since 6.2] std::chrono::milliseconds QLockFile::staleLockTimeAsDuration() const
잠금 파일이 유효하지 않은 것으로 간주되는 시점을 나타내는 std::chrono::milliseconds 객체를 반환합니다.
이 함수는 Qt 6.2에서 도입되었습니다.
setStaleLockTime()도 참조하십시오 .
bool QLockFile::tryLock(int timeout)
잠금 파일을 생성하려고 시도합니다. 이 함수는 잠금을 획득한 경우 ` true `를 반환하고, 그렇지 않은 경우 ` false`를 반환합니다. 다른 프로세스(또는 다른 스레드)가 이미 잠금 파일을 생성한 경우, 이 함수는 잠금 파일이 사용 가능해질 때까지 최대 ` timeout ` 밀리초 동안 대기합니다.
참고: timeout 매개변수로 음수를 전달하는 것은 lock()를 호출하는 것과 동일합니다. 즉, timeout 가 음수인 경우 이 함수는 잠금 파일을 잠글 수 있을 때까지 무한정 대기합니다.
잠금이 획득된 경우, 다른 프로세스(또는 스레드)가 해당 파일을 성공적으로 잠글 수 있으려면 unlock()을 사용하여 잠금을 해제해야 합니다.
먼저 잠금을 해제하지 않고 동일한 스레드에서 동일한 잠금에 대해 이 함수를 여러 번 호출하는 것은 허용되지 않으며, 파일을 재귀적으로 잠그려고 할 때 이 함수는 항상 false를 반환합니다.
[since 6.2] bool QLockFile::tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero())
잠금 파일을 생성하려고 시도합니다. 이 함수는 잠금을 획득한 경우 ` true `를 반환하고, 그렇지 않은 경우 ` false`를 반환합니다. 다른 프로세스(또는 다른 스레드)가 이미 잠금 파일을 생성한 경우, 이 함수는 잠금 파일이 사용 가능해질 때까지 최대 ` timeout ` 동안 대기합니다.
잠금을 획득한 경우, 다른 프로세스(또는 스레드)가 해당 파일을 성공적으로 잠글 수 있도록 하기 전에 unlock()을 사용하여 잠금을 해제해야 합니다.
먼저 잠금을 해제하지 않고 동일한 스레드에서 동일한 잠금에 대해 이 함수를 여러 번 호출하는 것은 허용되지 않으며, 파일을 재귀적으로 잠그려고 시도할 때 이 함수는 항상 false를 반환합니다.
이 함수는 오버로드된 함수입니다.
이 함수는 Qt 6.2에서 도입되었습니다.
void QLockFile::unlock()
잠금 파일을 삭제하여 잠금을 해제합니다.
파일을 먼저 잠그지 않은 상태에서 unlock()을 호출하면 아무런 동작도 수행되지 않습니다.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.