CS(Computer Science)/UNIX

UNIX - [Record Locking]

seongmik 2023. 1. 3. 12:00
반응형

 

사용법

#include <fcntl.h>
int fcntl(int filedes, int cmd, struct flock *ldata);

/*
> filedes : lock을 설정 하려는 file의 descriptor
		> read-lock은 O_RDONLY/O_RDWR로 open된 file에 한해서 적용 가능
		> write-lock은 O_WRONLY/O_RDWR로 open된 file에 한해서 적용 가능

> cmd :
		> F_GETLK : lock 정보 얻기
				> 해당 정보는 세 번째 인수에 저장
		> F_SETLK : non-blocking locking or unlocking 
				> lock 설정에 관한 자세한 정보는 세 번째 인수에 지정
		> F_SETLKW : blocking locking
				> lock 설정에 관한 자세한 정보는 세 번째 인수에 지정

> struct flock *ldata
		> short l_type : lock의 type
				> F_RDLCK, F_WRLCK, F_UNLCK / readlock, writelock, unlock 
		> short l_whence :
				> SEEK_SET, SEEK_CUR, SEEK_END
		> off_t l_start : l_whence로 부터의 변위로 표현된 locked record의 시작 위치
		> off_t l_len : locked record의 길이
		> pid_t l_pid : F_GETLK의 경우만 유효
				> 누가 해당 file에 lock을 걸었나?
*/

 

  • lock 정보는 fork()에 의해 계승되지 않는다.
  • 모든 lock은 프로세스 종료 시 자동으로 unlock 된다.

 

교착상태 (Deadlock)

  • 교착상태란?
  • 교착상태를 알아낼 수 있는가?
    • F_SETLKW 명령에 대해 –1 return
    • errno는 EDEADLK

 

locking의 사용 예

int main(void){
		int fd, i, num;
		struct flock lock;
	
		fd=open("data1", O_RDWR|O_CREAT, 0600);
		lock.l_whence=SEEK_CUR;
		lock.l_len=sizeof(int);
	
		for (i=0; i<10; i++){ 
				lock.l_type=F_WRLCK; 
				lock.l_start=0;
				fcntl(fd, F_SETLKW, &lock); 

				read(fd, &num, sizeof(int)); 
				num=num+10;sleep(1);
				lseek(fd, -sizeof(int), SEEK_CUR); 
				write(fd, &num, sizeof(int)); 

				lock.l_type=F_UNLCK; 
				lock.l_start=-sizeof(int);
				fcntl(fd, F_SETLK, &lock); 
		}
		lseek(fd, 0, SEEK_SET); 
		for (i=0; i<10; i++){
				read(fd, &num, sizeof(int));
				printf("%d\\n", num); 
		}
		return 0; 
}

 

레코드 락킹의 주의사항

레코드 락킹을 걸더라도 다른 프로그램이 내가 lock을 건 프로그램의 Lock을 무시하고 메모리에 접근할 수 있다.

그 이유는 무엇일까?

OS는 메모리 접근을 관리하는게 아니라 LOCK만을 관리하는 것이다. 그래서 lock이 걸린 메모리에 또 lock을 할 때만 막는 것이다.

따라서 내가 recode locking을 이용해서 트렌젝션을 구현, 즉 데이터 접근을 막으려고 한다면 모든 메모리접근에 Lock을 써야한다.

반응형