Liux 에서 flock,lockf 와 fcntl 의 차 이 를 이야기 합 니 다.

9979 단어 fcntllockfflocklinux
우선 flock 과 fcntl 은 시스템 호출 이 고 lockf 는 라 이브 러 리 함수 입 니 다.lockf 는 실제 fcntl 의 패키지 이기 때문에 lockf 와 fcntl 의 바 텀 실현 은 같 고 파일 에 자 물 쇠 를 추가 하 는 효과 도 같 습 니 다.뒤에 서로 다른 점 을 분석 할 때 대부분의 상황 은 fcntl 과 lockf 를 함께 놓 는 것 이다.다음은 먼저 각 함수 의 사용 을 보고 사용 하 는 방식 과 효 과 를 보면 각 함수 의 차 이 를 볼 수 있다.
 1. flock
함수 원형
int flock(int fd, int operation);  // fd 가 지정 한 열 린 파일 에 advisory lock 을 적용 하거나 제거 합 니 다.권장 잠 금 일 뿐 입 니 다.
그 중에서 fd 는 시스템 호출 open 에서 돌아 오 는 파일 설명자 입 니 다.operation 의 옵션 은 다음 과 같 습 니 다.
     1.LOCK_SH:공유 자물쇠
     2.LOCK_EX:배타 적 자물쇠 또는 독점 자물쇠
     3.LOCK_UN:잠 금 해제.
     4.LOCK_NB:비 차단(상기 세 가지 조작 과 함께 사용)
flock 함수 에 대해 서 는 먼저 flock 함수 가 전체 파일 에 만 잠 글 수 있 고 파일 의 일부분 에 잠 글 수 없다 는 것 을 알 아야 합 니 다.이것 은 fcntl/lockf 의 첫 번 째 중요 한 차이 점 입 니 다.후 자 는 파일 의 특정한 구역 에 잠 글 수 있 습 니 다.그 다음으로 플 로 크 는 권고 적 자물쇠 만 생 길 수 있다.Liux 에 강제 잠 금(mandatory lock)과 권고 잠 금(advisory lock)이 존재 한 다 는 것 을 알 고 있 습 니 다.강제 자물쇠 라 는 것 은 이해 하기 쉽 습 니 다.바로 당신 집 대문 에 있 는 자물쇠 입 니 다.가장 중요 한 것 은 열쇠 가 하나 밖 에 없고 프로 세 스 만 조작 할 수 있 습 니 다.권고 자물쇠 란 본질 적 으로 협의 입 니 다.파일 에 접근 하기 전에 자 물 쇠 를 먼저 검사 해 야 합 니 다.이 럴 때 자 물 쇠 는 그 역할 을 합 니 다.만약 당신 이 그렇게 kind 가 아니라면 무작정 읽 고 써 야 합 니 다.그러면 권고 자 물 쇠 는 아무런 역할 도 하지 않 습 니 다.협 의 를 지 키 고 쓰기 전에 잠 긴 프로 세 스 를 먼저 검사 하 는 것 을 합작 프로 세 스 라 고 합 니 다.또한,flock 과 fcntl/lockf 의 차 이 는 주로 fork 와 dup 에 있 습 니 다.
(1)flock 이 만 든 자 물 쇠 는 fd 가 아 닌 파일 열기 표 항목(struct file)과 연 결 됩 니 다.이것 은 파일 fd 를 복사 한 후,이 두 fd 를 통 해 이 자 물 쇠 를 조작 할 수 있 음 을 의미 합 니 다(예 를 들 어 하나의 fd 를 통 해 자 물 쇠 를 추가 하고,다른 fd 를 통 해 자 물 쇠 를 풀 수 있 음).즉,하위 프로 세 스 가 부모 프로 세 스 의 자 물 쇠 를 계승 하 는 것 입 니 다.그러나 잠 금 과정 에서 fd 중 하 나 를 닫 으 면 잠 금 이 풀 리 지 않 습 니 다(file 구조 가 풀 리 지 않 았 기 때 문).복 사 된 fd 를 모두 닫 아야 잠 금 이 풀 립 니 다.테스트 프로그램 입 프로그램 1.
프로그램 1

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>

int main (int argc, char ** argv)

{

  int ret;

  int fd1 = open("./tmp.txt",O_RDWR);

  int fd2 = dup(fd1);

  printf("fd1: %d, fd2: %dn", fd1, fd2);

  ret = flock(fd1,LOCK_EX);

  printf("get lock1, ret: %dn", ret);

  ret = flock(fd2,LOCK_EX);

  printf("get lock2, ret: %dn", ret);

  return 0;
 
실행 결 과 는 그림 과 같이 fd1 에 자 물 쇠 를 잠 그 고 프로그램 이 fd2 를 통 해 자 물 쇠 를 잠 그 는 데 영향 을 주지 않 습 니 다.부자 의 진행 과정 에 대해 서 는 절차 2 를 참고 하 세 요.
절차 2

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/file.h>

int main (int argc, char ** argv)

{

  int ret;

  int pid;

  int fd = open("./tmp.txt",O_RDWR);

  if ((pid = fork()) == 0){

    ret = flock(fd,LOCK_EX);

    printf("chile get lock, fd: %d, ret: %dn",fd, ret);

    sleep(10);

    printf("chile exitn");

    exit(0);

  }

  ret = flock(fd,LOCK_EX);

  printf("parent get lock, fd: %d, ret: %dn", fd, ret);

  printf("parent exitn");

  return 0;

}

실행 결 과 는 그림 과 같 습 니 다.하위 프로 세 스 는 자 물 쇠 를 가지 고 있 습 니 다.부모 프로 세 스 가 같은 fd 를 통 해 자 물 쇠 를 가 져 오 는 데 영향 을 주지 않 습 니 다.반대로 도 마찬가지 입 니 다.
(2)open 을 사용 하여 같은 파일 을 두 번 열 면 두 개의 fd 는 독립 적 입 니 다.(밑 에 두 개의 file 대상 에 대응 하기 때 문)그 중 하 나 를 통 해 자 물 쇠 를 추가 하고 다른 하 나 를 통 해 자 물 쇠 를 풀 수 없 으 며 앞의 자 물 쇠 를 풀 기 전에 도 자 물 쇠 를 잠 글 수 없습니다.테스트 프로그램:
프로 세 스 3 

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/file.h>

int main (int argc, char ** argv)

{

  int ret;

  int fd1 = open("./tmp.txt",O_RDWR);

  int fd2 = open("./tmp.txt",O_RDWR);

  printf("fd1: %d, fd2: %dn", fd1, fd2);

  ret = flock(fd1,LOCK_EX);

  printf("get lock1, ret: %dn", ret);

  ret = flock(fd2,LOCK_EX);

  printf("get lock2, ret: %dn", ret);

  return 0;

}

결 과 는 그림 과 같이 fd1 을 통 해 자 물 쇠 를 가 져 온 후 fd2 를 통 해 자 물 쇠 를 가 져 올 수 없습니다.
(3)exec 를 사용 하면 파일 잠 금 상태 가 변 하지 않 습 니 다.
(4)flock 은 NFS 파일 시스템 에서 사용 할 수 없습니다.NFS 에서 파일 잠 금 을 사용 하려 면 fcntl 을 사용 하 십시오.
(5)flock 자 물 쇠 는 재 귀 할 수 있 습 니 다.즉,dup 또는 fork 를 통 해 발생 하 는 두 개의 fd 는 모두 자 물 쇠 를 추가 하여 자물쇠 가 생기 지 않 습 니 다.
2.lockf 와 fcntl
함수 원형#include int lockf(int fd, int cmd, off_t len);fd 는 open 을 통 해 돌아 오 는 파일 설명 자 를 엽 니 다.
cmd 의 추출 값 은:
      F_LOCK:파일 에 자 물 쇠 를 채 우 고 자 물 쇠 를 채 우 면 자물쇠 가 풀 릴 때 까지 막 힙 니 다.
      F_TLOCK:동 FLOCK,그러나 파일 이 잠 겨 있 으 면 막 히 지 않 고 오 류 를 되 돌려 줍 니 다.
      F_ULOCK:잠 금 해제.
      F_TEST:파일 이 잠 겨 있 는 지 테스트 합 니 다.잠 겨 있 지 않 으 면 0 으로 돌아 갑 니 다.그렇지 않 으 면-1 로 돌아 갑 니 다.
      len:파일 의 현재 위치 에서 시작 하기 위 한 길이 입 니 다.
함수 매개 변수 기능 을 통 해 lockf 는 배타 적 자물쇠 만 지원 하고 공유 자 물 쇠 는 지원 하지 않 음 을 알 수 있 습 니 다.

#include 
#include 
int fcntl(int fd, int cmd, ... /* arg */ );
struct flock {
... 
short l_type;/* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */ 
off_t l_start;  /* Starting offset for lock */ 
off_t l_len;   /* Number of bytes to lock */ 
pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) */ 
...    
  }; 
파일 기록 잠 금 관련 cmd 는 세 가지 로 나 뉜 다.
       F_SETLK:자물쇠 신청(자물쇠 읽 기 FRDLCK,자물쇠 FWRLCK)또는 석방 소(FUNLCK),그러나 kernel 이 이 프로 세 스에 자 물 쇠 를 부여 할 수 없다 면(다른 프로 세 스에 게 먼저 자 물 쇠 를 빼 앗 겼 고 자 물 쇠 를 차지 했다)바보 같이 되 돌아 오지 않 습 니 다.error.
       F_SETLKW:와 FSETLK 는 거의 똑 같 습 니 다.유일한 차이 점 입 니 다.이 녀석 은 고지식 한 사람 입 니 다.신청 하지 못 하면 바보 같이 기다 리 고 있 습 니 다.
       F_GETLK:이 인 터 페 이 스 는 자물쇠 에 대한 정 보 를 가 져 옵 니 다.이 인 터 페 이 스 는 우리 가 들 어 오 는 struct flock 을 수정 합 니 다.
함수 매개 변수 기능 을 통 해 알 수 있 듯 이 fcntl 은 기능 이 가장 강하 다.공유 자물쇠 도 지원 하고 배타 자 물 쇠 를 지원 한다.즉,전체 파일 을 잠 글 수 있 고 파일 의 일부분 만 잠 글 수 있다.
fcntl/lockf 의 특성 을 보 겠 습 니 다:
       (1)자 물 쇠 를 잠 그 면 재 귀적 할 수 있 습 니 다.만약 에 프로 세 스 가 파일 구간 에 자 물 쇠 를 하나 더 추가 하려 고 하면 새 자 물 쇠 는 오래된 자 물 쇠 를 교체 합 니 다.
       (2)읽 기 자물쇠(공유 자물쇠)파일 은 읽 기 열 려 있어 야 하고,쓰기 자물쇠(배타 자물쇠)파일 은 쓰기 열 려 있어 야 한다.
       (3)프로 세 스 는 F 를 사용 할 수 없습니다.GETLK 명령 은 파일 의 일부분 에 자 물 쇠 를 가지 고 있 는 지 확인 합 니 다.F_GETLK 명령 정 의 는 기 존 잠 금 이 호출 프로 세 스 의 잠 금 설정 을 막 는 지 여 부 를 알려 줍 니 다.왜냐하면,FSETLK 와 FSETLKW 명령 은 항상 프로 세 스 의 기 존 자 물 쇠 를 교체 하기 때문에 호출 프로 세 스 는 자신 이 가지 고 있 는 자 물 쇠 를 막 지 않 습 니 다.그래서 FGETLK 명령 은 호출 프로 세 스 가 가지 고 있 는 자 물 쇠 를 보고 하지 않 습 니 다.
       (4)프로 세 스 가 종 료 될 때 그 가 만 든 모든 파일 잠 금 이 풀 리 고 팀 닥 터 플 로 크 도 마찬가지 입 니 다.
       (5)설명 자 를 닫 을 때 이 프로 세 스 는 이 설명 자 를 통 해 참조 할 수 있 는 파일 의 모든 자 물 쇠 를 풀 어 줍 니 다(이 자 물 쇠 는 이 프로 세 스 가 설정 한 것 입 니 다).이 점 은 flock 과 다 릅 니 다.예:

fd1 = open(pathname, …);

lockf(fd1, F_LOCK, 0);

fd2 = dup(fd1);

close(fd2);
close(fd2)후 fd1 에 설 치 된 자물쇠 가 풀 립 니 다.dup 를 open 으로 바 꾸 면 다른 설명자 에 있 는 같은 파일 을 열 면 효과 도 마찬가지 입 니 다.

fd1 = open(pathname, …);

lockf(fd1, F_LOCK, 0);

fd2 = open(pathname, …);

close(fd2);
        (6)fork 에서 생 성 된 하위 프로 세 스 는 부모 프로 세 스 가 설정 한 자 물 쇠 를 계승 하지 않 습 니 다.이 점 은 flock 과 다 릅 니 다.
        (7)exec 를 실행 한 후 새 프로그램 은 원래 프로그램의 자 물 쇠 를 계승 할 수 있 습 니 다.이 점 은 flock 과 같 습 니 다.(fd 에 close-on-exec 를 설정 하면 exec 전에 fd 를 닫 고 해당 파일 의 자물쇠 도 풀 립 니 다).
        (8)강제 잠 금 지원:특정 파일 의 설정 그룹 ID 위치 열기(SISGID),그룹 실행 위치 닫 기(SIXGRP)는 이 파일 에 강제 잠 금 메커니즘 을 열 었 다.리 눅 스에 서 강제 잠 금 을 사용 하려 면 파일 시스템 mount 에서 를 사용 해 야 합 니 다.omand 에서 이 메커니즘 을 엽 니 다.
3.두 가지 자물쇠 의 관계
그렇다면 플 로 크 와 lockf/fcntl 의 자 물 쇠 는 어떤 관계 가 있 습 니까?답 은 서로 영향 을 주지 않 는 다.테스트 프로그램 은 다음 과 같 습 니 다.

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/file.h>

int main(int argc, char **argv)

{

  int fd, ret;

  int pid;

  fd = open("./tmp.txt", O_RDWR);

  ret = flock(fd, LOCK_EX);

  printf("flock return ret : %dn", ret);

  ret = lockf(fd, F_LOCK, 0);

  printf("lockf return ret: %dn", ret);

  sleep(100);

  return 0;

}
테스트 결 과 는 다음 과 같다.

$./a.out

flock return ret : 0

lockf return ret: 0
flock 의 잠 금 을 볼 수 있 습 니 다.lockf 의 잠 금 에 영향 을 주지 않 습 니 다.또한 우 리 는/proc/locks프로 세 스 를 통 해 잠 금 상 태 를 가 져 올 수 있 습 니 다.
$ps aux | grep a.out | grep -v grep
123751   18849  0.0  0.0  11904   440 pts/5    S+   01:09   0:00 ./a.out
$sudo cat /proc/locks | grep 18849
1: POSIX  ADVISORY  WRITE 18849 08:02:852674 0 EOF
2: FLOCK  ADVISORY  WRITE 18849 08:02:852674 0 EOF
우 리 는/proc/locks 아래 에 자물쇠 가 있 는 정 보 를 볼 수 있다.나 는 지금 각각 의 미 를 서술 하고 있다.
       1)POSIX FLOCK 는 어떤 종류의 자물쇠 인지 명확 하 다.flock 시스템 호출 은 FLOCK,fcntl 호출 FSETLK,F_SETLKW 나 lockf 는 POSIX 형식 으로 두 가지 호출 에 의 한 자물쇠 의 유형 이 다르다 는 것 을 알 수 있 습 니 다.
       2)ADVISORY 는 권고 자물쇠 임 을 나타 낸다.
       3)WRITE 는 말 그대로 자 물 쇠 를 쓰 고 자 물 쇠 를 읽는다.
       4)18849 는 자 물 쇠 를 가 진 프로 세 스 ID 입 니 다.물론 플 로 크 와 같은 유형의 잠 금 은 프로 세 스 가 종료 되 었 을 때 발생 합 니 다.
       5)08:02:852674 는 디스크 파일 에 대응 하 는 장치 의 주 장치 가 좋 고 차 장치 번호,그리고 파일 에 대응 하 는 inode number 를 표시 합 니 다.
       6)0 은 실제 위 치 를 나타 낸다.
       7)EOF 는 끝 자 리 를 나타 낸다.이 두 필드 는 fcntl 형식 에 비교적 유용 하 며,flock 에 대해 서 는 항상 0 과 EOF 입 니 다.
이상 은 Liux 에서 fcntl(),lockf 와 flock 의 차이 점 의 모든 내용 입 니 다.본 고 는 여러분 에 게 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기