다음 위로 이전 목차 리눅스 프로그래머를 위한 가이드

시스템 호출:semop() (SYSTEM CALL:semop())


  SYSTEM CALL: semop();                                                          
  PROTOTYPE: int semop ( int semid, struct sembuf *sops, unsigned nsops);
    RETURNS: 0 on success (all operations performed)
             -1 on error: errno = E2BIG (nsops greater than max number of ops allowed atomically)
                                  EACCESS (permission denied)
                                  EAGAIN (IPC_NOWAIT asserted, operation could not go through)
                                  EFAULT (invalid address pointed to by sops argument)
                                  EIDRM (semaphore set was removed)
                                  EINTR (Signal received while sleeping)
                                  EINVAL (set doesn't exist, or semid is invalid)
                                  ENOMEM (SEM_UNDO asserted, not enough memory to create the
                                          undo structure necessary)
                                  ERANGE (semaphore value out of range)
  NOTES:

semop()의 첫번째 아구먼트는 semget() 호출에 의해 반환된 키값이다. 두번째 아규먼트(sops)는 세마퍼 집합에서 수행될 동작 배열을 가리키는 포인터이고 세번째 아규먼트(nsops)는 배열안에 있는 동작의 갯수이다.

sops 아규먼트는 sembuf 타입의 배열을 가리킨다. 이 구조는 다음과 같이 linux/sem.h에 선언되어 있다.:


	/* semop 시스템 호출은 이러한 배열을 갖는다 */
        struct sembuf {
                ushort  sem_num;        /* 배열안에서의 세마퍼 인덱스 */
                short   sem_op;         /* 세마퍼 동작 */
                short   sem_flg;        /* 동작 플래그 */
        };

sem_num
다루고자 하는 세마퍼의 번호
sem_op
수행할 동작 (양수,음수, 또는 0)
sem_flg
동작 플래그
sem_op가 음수이면, 세마퍼로 부터 그값을 뺀다. 이것은 세마퍼가 접근을 감시하고 통제하는 자원들을 사용함을 의미한다. IPC_NOWAIT가 지정되지 않았으면, 호출한 프로세스는 자원의 요청한 양만큼 세마퍼에서 사용가능할 때까지 잠을 잔다. (또 다른 프로세스가 그것을 놓을 때까지)

sem_op가 양수이면, 그값은 세마퍼에 더해진다. 이것은 응용프로그램의 세마퍼 집합에게 자원을 돌려준다는 것을 의미한다. 자원들은 더 이상 필요하지 않을 때 세마퍼 집합에게 돌려주어야 한다.

끝으로, sem_op가 0(zero)이면, 호출한 프로세스는 세마퍼의 값이 0이 될때까지 잠을 잘 것이다. 이것은 세마퍼가 100% 활용될 때까지 기다린다는 것을 의미한다. 이러한 좋은 예는 100% 활용에 도달하도록 세마퍼의 크기를 동적으로 조정하는, 수퍼유저(superuser)의 권한을 가지고 수행되는 대몬(daemon)일 것이다.

sem_op 호출을 설명하기 위하여, 우리의 인쇄방 시나리오를 다시 한번 생각해보자. 한번에 한가지 일만을 수행할 수 있는 오직 한대의 프린터만 있다고 가정하자. 우리는 한개의 세마퍼(한개의 프린터)만을 가진 세마퍼 집합을 만들고 세마퍼의 초기값을 1로 초기화한다.(한번에 한가지 일)

우리가 이 프린터에 작업을 보내고자 할 때마다, 자원이 이용가능한지를 확인해야할 필요가 있다. 우리는 세마퍼로 부터 한개의 단위(unit)를 얻는 것으로 이러한 작업을 수행한다. 동작을 수행하기 위해 sembuf 배열을 적재(load)하자.:


       struct sembuf sem_lock = { 0, -1, IPC_NOWAIT };

위와같이 -1값으로 초기화된 구조의 변환은 세마퍼 집합안에서 세마퍼 번호 0에 첨가된다. 바꾸어 말하면, 자원들의 한 단위(one unit)는 오직 집합안의 세마퍼(0th member)로 부터 얻어진다. IPC_NOWAIT가 지정되면 호출은 즉시 통과하거나 다른 인쇄작업이 수행 중이면 실패한다. 여기 semop 시스템 호출을 가지고 초기화된 sembuf 구조를 사용하는 예가 있다.:


        if((semop(sid, &sem_lock, 1) == -1)
                perror("semop");

세번째 아규먼트(nsops)는 우리가 오직 한개의 동작만을 수행하고 있음을 말해주고 있다. (동작 배열안에 오직 한개의 sembuf 구조만이 있다.) sid 아규먼트는 세마퍼 집합에 대한 IPC 확인자(identifier)이다.

인쇄작업이 완료되었을 때, 세마퍼 집합으로 자원을 돌려주어야 한다. 그래야 다른 사람이 프린터를 사용할 수 있다.


       struct sembuf sem_unlock = { 0, 1, IPC_NOWAIT };

위와 같이 '1'값이 지정된 초기화된 구조의 변환은 세마퍼 집합내의 0번 세마퍼에 적용된다. 바꾸어 말하면, 자원들의 한 단위(one unit)가 집합으로 반환된다.


이전:시스템 호출:semget() (SYSTEM CALL:semget()) 다음:시스템 호출:semctl() (SYSTEM CALL:semctl())

Copyright (c) 1996,1997 by Euibeom.Hwang & SangEun.Oh All Rights Reserved

Email To:Webmaster , Another address
LAST UPDATE Nov 25,1997
Created Nov 25,1997