[리눅스 프로그래밍] (IPC) File lock

Yoon Yeoung-jin·2022년 7월 17일
0

Linux

목록 보기
13/13

01. File lock

Semaphore와 비슷한 개념으로 이는 여러 프로세스 또는 스레드가 하나의 파일을 열어서 작업할 경우 데이터 충돌을 줄이고자 사용되는 기법이다. 이러한 locking 기법은 두가지가 존재한다.

  • advisory locking
    • locking 하기로 한 프로세스간에 locking
    • 관련 없는 프로세스들은 이를 무시할 수 있다.
  • mandatory locking
    • 파일에 lock이 설정되면 다른 모든 프로세스가 이를 따라야 한다.

위 기법은 파일 locking의 대상자에 따라 구분되어있다. 하지만 file lock 기법은 이뿐만 아니라 locking 의 범위또한 설정 가능하다.

lock을 하는 시도에는 다음 두가지가 존재한다.

  • Shared lock
    • exclusive lcok이 잡혀있지 않으면 잡을 수 있다.
    • 즉, 여러 프로세스들이 shared lock을 잡고 있을 수 있다.
  • Exclusive lock
    • 아무런 lock이 잡혀있지 않으면 잡을 수 있다.

이러한 file lock을 사용하는데 주의해야될 부분이 있다. 바로 fork() API 를 사용할 때 이다. fork() API는 선언 시점에 자식 프로세스는 부모 프로세스의 모든 정보를 복사하여 생성된다. 이때 fork() 선언 전 lock 을 한 상태에서 fork를 하게되면 두개의 프로세스가 lock을 갖게 되어 의도치 않는 상황이 된다. 따라서 file lock 과 멀티 프로세스를 같이 사용한다면 lock 이 상속되지 않도록 주의해야 한다.

02. 사용 API

  • int flock(int fd, int operation); : 파일 단위의 file lock operation 을 수행한다. fork()시 자식 프로세스에 상속된다.
    파라미터
    • fd: file lock을 적용할 file descriptor 
    • operation
    	‐ LOCK_SH: shared lock 획득 시도
    	‐ LOCK_EX: exclusive lock 획득 시도
    	‐ LOCK_UN: 획득한 lock 해제
    	‐ LOCK_NB: non-blocking I/O, 위의 operation과 결합(ORing)
    반환값
    • 성공: 0
    • 실패: -1
  • int fcntl(int fd, int cmd, struct flock *flock); :파일의 특정 영역에 대해 file lock operation 수행. 이때 해당 함수는 fork()시 자식 프로세스에 상속되지 않으며, shared와 exclusive Lock 을 모두 지원한다.
    파라미터
    • fd: file lock을 적용할 file descriptor 
    • cmd
    	‐ F_SETLK: lock 획득/해제(non-blocking)
    		▫ l_type: F_RDLCK, F_WRLCK, F_UNLCK
    	‐ F_SETLKW: lock 획득/해제(blocking)
    	‐ F_GETLK: lock 가능 여부 요청(lock 불가 시 locked 되어 있는 정보 습득)
    • flock: record lock 영역 지정
    반환값
    • 성공: 0
    • 실패: -1
    • struct flock 구조체
      struct flock {
          ...
      		short l_type;    /* lock 획득: F_RDLCK, F_WRLCK lock 해제: F_UNLCK */ 
      		short l_whence;  /* l_start 기준점: SEEK_SET, SEEK_CUR, SEEK_END */ 
      		off_t l_start;   /* 시작 offset */
      		off_t l_len;     /* 길이 */
      		pid_t l_pid;     /* lock을 획득한 프로세스의 pid(F_GETLK and F_OFD_GETLK) */
      		...
      };
    • fcntl 함수의 cmd 변수를 아래와 같이 변경하면 open file descr.lock 을 사용할 수 있다. 이떄 이는 non-POSIX 임으로 리눅스 외에 다른 플렛폼에서 사용 못한다.
      ‐ F_OFD_SETLK: lock 획득/해제(non-blocking) 
      	▫ l_type: F_RDLCK, F_WRLCK, F_UNLCK
      ‐ F_OFD_SETLKW: lock 획득/해제(blocking)
      ‐ F_OFD_GETLK: lock 가능 여부 요청(lock 불가 시 locked 되어 있는 정보 습득)
  • int lockf(int fd, int cmd, off_t len); : 열린 파일의 특정 영역에 대해 file lock operation 을 수행, 이는 fork()시 자식 프로세스에 상속되지 않으며 exclusive lock만을 지원한다.
    파라미터
    • fd: file lock을 적용할 file descriptor 
    • cmd
    	‐ F_LOCK: 지정된 영역에 exclusive lock을 설정(maybe blocking)
    	‐ F_TLOCK: F_LOCK과 같지만 이미 lock 되어 있는 경우 error return(EACCES or EAGAIN)
    	‐ F_ULOCK: unlock
    	‐ F_TEST: lock 상태 테스트
    		▫ unlocked 상태이거나 이미 해당 프로세스가 lock한 경우라면 0 리턴, locked 상태이면 -1 리턴 
    • len: lock을 설정할 영역 지정(current file position 기준)
    반환값
    • 성공: 0
    • 실패: -1
  • void flockfile(FILE *filehandle); : blocking 모드로 lock 획득 시도
  • int ftrylockfile(FILE *filehandle); : non-blocking 모드로 lock 획득 시도
  • void funlockfile(FILE *filehandle); : lock 해제
    • 위 함수들은 libc layer 에서 FILE stream 자체에 대한 Lock 구현이다.

    • 한 process 내의 multi-thread 간에만 적용 가능한 locking mechanism

      파라미터
      • filehandle: lock을 걸기 위한 file handle
      반환값
      • ftrylockfile(): lock 획득 성공시 0, 실패시 -1 리턴
profile
신기한건 다 해보는 사람

0개의 댓글