Linux

#1 Linux

kminnnee 2022. 11. 2. 23:59

Linux 첫 게시글로 파일을 잠그는 일을 해보겠슴니다..
먼저
잠금( Lock ) : 2개 이상의 process 가 동시에 하나의 resource 에 접근하려고 할 때 생기는 문제점을 해결하기 위한 기법

위와 같이 2개의 프로세스가 한 파일에 동시에 접근하려 할때.. ( 2개 이상이 될 수 도 있겠죠 ) 

문제점이 발생합니다.

그래서 Lock 을 걸어서 생기는 문제점을 해결해 주어야 하는데요

위 사진은 프로세스 A가 lock 을 한 경우 입니다.

 

1. 프로세스A 가 Lock 을 걸고

2. read / write 실행 

3. 이때 프로세스 B가 접근하려 하지만 A의 Lock이 걸려있으므로 현재 접근 불가 

이때 B 는 2가지 경우를 생각해볼 수 있는데 

3-1 ) B가 Lock 을 얻지못한다면 에러를 return

3-2 ) A가 Lock 을 풀때까지 B 는 대기 return ( 이때도 대기 또는 에러 리턴 이라는 2가지 선택 가능 )

4. A가 Lock 을 푸는순간 ( = UnLock ) B 는 이제 접근 하고 싶은 파일을 읽거나 쓸수 있음 

5. B 도 Lock 

.

이라는 순서를 거치게 됩니다.

 

잠금 구현 함수 

int fcntl( int fd , int cmd, struct flock *lock )   

- 파일 및 레코드 잠금을 구현할 수 있음

- fd 는 대상이 되는 파일 디스크립터 

.

.

* flock 구조체 

struct flock 
{
short l_type; // 잠금 종류: F_RDLCK, F_WRLCK, F_UNLCK
off_t l_start; // 잠금 시작 위치: 바이트 오프셋
short l_whence; // 기준 위치: SEEK_SET, SEEK_CUR, SEEK_END
off_t l_len; // 잠금 길이: 바이트 수 (0이면 파일끝까지)
pid_t l_pid; // 프로세스 번호. 검사에만 필요

};

 

* 잠금의 종류

1) F_RDLCK : 여러 프로세스가 공유 가능한 읽기 잠금

2) F_WELCK : 한 프로세스만 가질 수 있는 배타적인 쓰기 잠금

 

*  cmd 

- F_GETLK : 잠금을 검사

- F_SETLK : 잠금 설정 혹은 해제 -> Lock 을 걸려고 시도 했을 때 다른 프로세스가 이미 Lock이 걸려있으면 에러를 리턴 ( -1 반환 ) 

- F_SETLKW : 잠금 설정 ( 대기 버전 ) 혹은 해제  ->  Lock 을 걸려고 시도 했을 때 다른 프로세스가 이미 Lock이 걸려있어도 대기 ( UnLock 이 되면 진입 ) 

 

Lock 의 예제를 살펴 보겠습니다 .

 

코드는 https://beej.us/guide/bgipc/html/multi/flocking.html  를 참고 했습니다 . 

 

File Locking

l_whence This field determines where the l_start field starts from (it's like an offset for the offset). It can be either SEEK_SET, SEEK_CUR, or SEEK_END, for beginning of file, current file position, or end of file.

beej.us

.

.

코드는 

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
/* l_type l_whence l_start l_len l_pid */

struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 };   // 즉 처음부터 끝까지 // 파일전체를 잠금
int fd;
fl.l_pid = getpid();      // 굳이 필요는 없다..

if (argc > 1)
	fl.l_type = F_RDLCK;

if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
	perror("open");
	exit(1);
}

printf("Press <RETURN> to try to get lock: ");
getchar();
printf("Trying to get lock...");

if (fcntl(fd, F_SETLKW, &fl) == -1) {    // 대기 , 잠금이 가능하면 fl 구조체처럼 잠금 설정지시
	perror("fcntl");
	exit(1);
}
printf("got lock\n");
printf("Press <RETURN> to release lock: ");
getchar();
fl.l_type = F_UNLCK; /* set to unlock same region */

if (fcntl(fd, F_SETLK, &fl) == -1) {      // lock 을 거는 위치와 푸는 위치는 같다
	perror("fcntl");
	exit(1);
}
printf("Unlocked.\n");
close(fd);
return 0;
}

를 실행하면 잘 작동이 되는 것을 확인할 수 있습니다.

 

'Linux' 카테고리의 다른 글

#4 Linux ( 시그널-alarm() )  (0) 2022.11.23
#3 Linux ( 프로그램 실행 )  (0) 2022.11.22
#2 Linux ( 프로세스 )  (0) 2022.11.22