2012. 7. 13. 16:31

파일을 이용해 프로세스간 통신하기

a.out
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

main(int argc, char *argv[])
{
    int fd;
    struct flock filelock;

    filelock.l_type = F_WRLCK;   /* 쓰기 잠금 */
    /* 파일 전체를 영역으로 */
    filelock.l_whence = SEEK_SET;
    filelock.l_start = 0;
    filelock.l_len = 0;

    /* argv[1] 파일을 여는데 없으면 생성 */
    fd = open(argv[1], O_RDWR | O_CREAT, 0666);

    /* fd 파일에 대해 쓰기 잠금을 설정 */
    if(fcntl(fd, F_SETLK, &filelock) == -1) {
       perror("fcntl failed");
       exit(1);
    }
    printf("locked %s\n", argv[1]);
    /* 파일에 데이터 쓰기 */
    write(fd, "Hi Linux", 9);
    sleep(5);
    printf("unlocked %s\n", argv[1]);
    /* 종료하면 레코드 잠금은 자동적으로 해제 */
    exit(0);
}

b.out
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define SIZE 20

main(int argc, char *argv[])
{
    int fd;
    struct flock filelock;
    char buffer[SIZE];
    int length;

    filelock.l_type = F_RDLCK;   /* 읽기 잠금 */
    /* 파일 전체를 영역으로 */
    filelock.l_whence = SEEK_SET;
    filelock.l_start = 0;
    filelock.l_len = 0;

    fd = open(argv[1], O_RDWR);   /* agrv[1] 파일 열기 */

    /* fd 파일에 대해 읽기 잠금을 설정.
      이미 레코드 잠금이 설정되어 있으면 해제될 때까지 기다림 */
    if(fcntl(fd, F_SETLKW, &filelock) == -1) {
       perror("fcntl failed");
       exit(1);
   }
    printf("locked %s\n", argv[1]);
    /* 파일에서 데이터 읽기 */
    length = read(fd, buffer, SIZE);
    /* 읽은 데이터를 표준 출력 장치에 출력 */
    write(STDOUT_FILENO, buffer, length);
    printf("unlocked %s\n", argv[1]);
    exit(0);
}

[localhost@local]#a.out file&
locked file
[localhost@local]#b.out file
unlocked file
locked file
Hi Linuxunlocked file

------------------------------------------------------------------------------------------------------
fcntl(fd, F_GETLK,&filelock);
위와 같이 cmd의 인수를 F_GETLK로 설정하면 filelock에 잠금 정보가 저장된다

레코드 잠금 정보 얻어오기

a.out
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

main(int argc, char *argv[])
{
    int fd;
    struct flock filelock;

    /* argv[1]의 내용이 “r”이면 F_RDLCK를, 아니면 F_WRLCK를 filelock.l_type에 저장 */
    filelock.l_type = (!strcmp(argv[1],"r"))?F_RDLCK:F_WRLCK;
    /* 파일 전체를 영역으로 */
    filelock.l_whence = SEEK_SET;
    filelock.l_start = 0;
    filelock.l_len = 0;

    /* argv[2] 파일을 여는데 없으면 생성 */
    fd = open(argv[2], O_RDWR | O_CREAT, 0666);

    /* fd 파일 즉, argv[2]에 대해 filelock 형태로 레코드 잠금을 설정 */
    if(fcntl(fd, F_SETLK, &filelock) == -1) {
       perror("fcntl failed");
       exit(1);
    }
    printf("locked %s\n", argv[2]);
    sleep(30);
    printf("unlocked %s\n", argv[2]);
    exit(0);
}

b.out
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

main(int argc, char *argv[])
{
    int fd;
    struct flock filelock;

    /* 쓰기 잠금 */
    filelock.l_type = F_WRLCK;
    /* 파일 전체 */
    filelock.l_whence = SEEK_SET;
    filelock.l_start = 0;
    filelock.l_len = 0;

    fd = open(argv[1], O_RDWR);

    /* fd 파일이 다른 프로세스에 의해 잠겨있어서 레코드 잠금에 실패하면 */
    if(fcntl(fd, F_SETLK, &filelock) == -1) {
       /* 레코드 잠금 정보를 filelock에 얻어 옴 */
       fcntl(fd, F_GETLK, &filelock);
       /* filelock.l_pid는 잠금을 설정하고 있는 프로세스의 프로세스 ID */
       fprintf(stderr, "%s locked by %d\n", argv[1], filelock.l_pid);
       exit(1);
    }
    exit(0);
}

[localhost@local]#a.out w file&
[1] 2000
locked file
[localhost@local]#b.out file&
file locked by 2000

Posted by 몰라욧