독서노트: 제9장 기록에 자물쇠(2)
3907 단어 독서 노트UNIX 네트워크 프로그래밍
fcntl 자물쇠의 추가 1 테스트
--------------------------------------------
/*
* lockmain.c
* 9-2 main
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define MAXLINE 1024
#define SEQFILE "seqno"
void my_lock(int fd);
void my_unlock(int fd);
int main(int argc, char *argv[])
{
int fd;
long i, seqno;
pid_t pid;
ssize_t n;
char line[MAXLINE + 1];
pid = getpid(); // ID
//
if ((fd = open(SEQFILE, O_RDWR, FILE_MODE)) < 0) {
fprintf(stderr, "open %s error: %s
", SEQFILE, strerror(errno));
exit(1);
}
for (i = 0; i < 20; i++) {
my_lock(fd); //
lseek(fd, 0L, SEEK_SET); //
if ((n = read(fd, line, MAXLINE)) < 0) { //
fprintf(stderr, "read error: %s
", strerror(errno));
exit(1);
}
line[n] = '\0';
n = sscanf(line, "%ld
", &seqno); //
printf("%s: pid = %d, seq# = %ld
", argv[0], pid, seqno);
seqno++; // 1
snprintf(line, sizeof(line), "%ld
", seqno); //
lseek(fd, 0L, SEEK_SET); //
if (write(fd, line, strlen(line)) < 0) { //
fprintf(stderr, "write error: %s
", strerror(errno));
exit(1);
}
my_unlock(fd); //
}
exit(0);
}
/*
* lockfcntl.c
* P161 9-3 fcntl
*/
void my_lock(int fd)
{
struct flock lock;
lock.l_type = F_WRLCK; //
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
//
if (fcntl(fd, F_SETLKW, &lock) < 0) {
fprintf(stderr, "fcntl error: %s
", strerror(errno));
}
return; // ,
}
void my_unlock(int fd)
{
struct flock lock;
lock.l_type = F_UNLCK; //
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
//
if (fcntl(fd, F_SETLK, &lock) < 0) {
fprintf(stderr, "fcntl error: %s
", strerror(errno));
}
return; // ,
}
--------------------------------------------
seqno 파일을 만들고 1에 기록합니다.프로그램 실행:
$ ./lockmain & ./lockmain &
[1] 2513
[2] 2514
$ ./lockmain: pid = 2513, seq# = 1
./lockmain: pid = 2513, seq# = 2
./lockmain: pid = 2513, seq# = 3
./lockmain: pid = 2513, seq# = 4
./lockmain: pid = 2513, seq# = 5
./lockmain: pid = 2513, seq# = 6
./lockmain: pid = 2513, seq# = 7
./lockmain: pid = 2513, seq# = 8
./lockmain: pid = 2513, seq# = 9
./lockmain: pid = 2513, seq# = 10
./lockmain: pid = 2513, seq# = 11
./lockmain: pid = 2513, seq# = 12
./lockmain: pid = 2513, seq# = 13
./lockmain: pid = 2513, seq# = 14
./lockmain: pid = 2513, seq# = 15
./lockmain: pid = 2513, seq# = 16
./lockmain: pid = 2513, seq# = 17
./lockmain: pid = 2513, seq# = 18
./lockmain: pid = 2513, seq# = 19
./lockmain: pid = 2513, seq# = 20
./lockmain: pid = 2514, seq# = 21
./lockmain: pid = 2514, seq# = 22
./lockmain: pid = 2514, seq# = 23
./lockmain: pid = 2514, seq# = 24
./lockmain: pid = 2514, seq# = 25
./lockmain: pid = 2514, seq# = 26
./lockmain: pid = 2514, seq# = 27
./lockmain: pid = 2514, seq# = 28
./lockmain: pid = 2514, seq# = 29
./lockmain: pid = 2514, seq# = 30
./lockmain: pid = 2514, seq# = 31
./lockmain: pid = 2514, seq# = 32
./lockmain: pid = 2514, seq# = 33
./lockmain: pid = 2514, seq# = 34
./lockmain: pid = 2514, seq# = 35
./lockmain: pid = 2514, seq# = 36
./lockmain: pid = 2514, seq# = 37
./lockmain: pid = 2514, seq# = 38
./lockmain: pid = 2514, seq# = 39
./lockmain: pid = 2514, seq# = 40
[1]- ./lockmain
[2]+ ./lockmain
이 실행 결과는 정확해 보이지만, 프로그램이 정상적으로 작동하는지 알려주기에는 부족하다.20번만 순환하고, 두 프로세스가 중간에 전환되지 않으면, 우리는 영원히 오류를 발견할 수 없을 것이다.더 많은 순환 횟수의 테스트가 필요합니다.