C semop() 세마포어 값을 변경 함수
semop() 함수는 세마포어의 값을 변경합니다. 세마포어를 사용하기 위해서는 먼저 세마포어 값을 1 감소시키고, 사용 후에는 1 증가시키는데, 이렇게 세마포어값을 증감하는 것을 요청하는 함수입니다.
- 헤더: sys/types.h, sys/ipc.h, sys/sem.h
- 형태: int semop ( int semid, struct sembuf *sops, unsigned nsops )
- 인수: int semid 시스템에서 세머포어를 식별하는 집합 번호
struct sembuf *sops 세마포어 값을 계사하기위한 설정 값
unsigned nsops 변경하려는 세마포어 개수로 변경하려는 세마포어 개수가 여러 개일 때 사용합니다. - 반환: 0 == 성공, -1 == 실패
struct sembuf *sops 세마포어 값을 계사하기위한 설정 값
struct sembuf {
short sem_num; 세마포어 번호
short sem_op; 세마포어 증감값
short sem_flg; 옵션
}
struct sembuf *sops 세마포어 값을 계사하기위한 설정 값
sem_flg | 내용 |
IPC_NOWAIT | 호출 즉시 실행하지 못했을 경우 기다리지 않고 실패로 바로 복귀합니다. |
SEM_UNDO | 프로세스가 종료되면 시스템에서 세마포어 설저을 원래 상태로 되돌립니다. 그러므로 보통 이 옵션을 사용합니다. |
unsigned nsops 변경하려는 세마포어 개수로 변경하려는 세마포어 개수가 여러 개일 때 사용합니다. 예를 들어 변경하려는 세마포어 개수가 한 개라면
struct sembuf sbuf = { 0, -1, 0};
semop( semmop, &sbuf, 1);
이렇게 값이 1이 되지만 한번에 2개 이상의 세마포어를 변경한다면,
struct sembuf pbuf[2] = {
{ 0, 1, 0} , // 첫번째 세마포어 값을 1 증가
{ 1, -1, 0} // 두번째 세마포어 값을 1 감소
}
semop( semmop, pbuf, 2);
C언어 semop() 함수 예제
예제에서는 두개의 쓰레드를 만들어 첫번째 쓰레드는 카운터 값을 증가 시키고 두번째 쓰레드는 카운터를 화면에 출력합니다. 카운터가 5 이상의 값이 되면 두 개의 쓰레드는 모두 종료하고 프로그램이 종료되면서 세마포어를 삭제합니다.
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int cnt = 0;
static int semid;
void p()
{
struct sembuf pbuf;
pbuf.sem_num = 0;
pbuf.sem_op = -1;
pbuf.sem_flg = SEM_UNDO;
if ( -1 == semop(semid, &pbuf, 1))
printf( "p()-semop() 실행 오류\n");
}
void v()
{
struct sembuf vbuf;
vbuf.sem_num = 0;
vbuf.sem_op = 1;
vbuf.sem_flg = SEM_UNDO;
if ( -1 == semop( semid, &vbuf, 1))
printf( "v()-semop() 실행 오류\n");
}
void *fun_thread1(void *arg)
{
while( 1){
p();
printf( "thread1 실행\n");
if ( 5 < cnt){
printf( "thread1 완전 종료\n");
v();
break;
} else {
cnt++;
usleep( 100);
printf( "thread1 완료\n");
}
v();
}
return NULL;
}
void *fun_thread2(void *arg)
{
while( 1){
p();
printf( "thread2 실행\n");
if ( 5 < cnt){
printf( "thread2 완전 종료\n");
v();
break;
} else {
printf( "카운터= %d\n", cnt);
usleep( 100);
printf( "thread2 완료\n");
}
v();
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread1;
pthread_t thread2;
union semun{
int val;
struct semid_ds *buf;
unsigned short int *arrary;
} arg;
if ( -1 == (semid = semget( IPC_PRIVATE, 1, IPC_CREAT ¦ 0666))){
printf( "semget() 실행 오류\n");
return -1;
}
arg.val = 1; // 세마포어 값을 1로 설정
if ( -1 == semctl(semid, 0, SETVAL, arg)){
printf( "semctl()-SETVAL 실행 오류\n");
return -1;
}
pthread_create(&thread1, NULL, fun_thread1, NULL);
pthread_create(&thread2, NULL, fun_thread2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
if ( -1 == semctl(semid, 0, IPC_RMID, arg)){
printf( "semctl()-IPC_RMID 실행 오류\n");
return -1;
}
printf( "프로그램 종료\n");
return 0;
}
C언어 semop() 예제 실행 결과
]$ gcc test.c -lpthread
]$ ./a.out
thread2 실행
카운터= 0
thread2 완료
thread1 실행
thread1 완료
thread2 실행
카운터= 1
thread2 완료
thread1 실행
thread1 완료
thread2 실행
카운터= 2
thread2 완료
thread1 실행
thread1 완료
thread2 실행
카운터= 3
thread2 완료
thread1 실행
thread1 완료
thread2 실행
카운터= 4
thread2 완료
thread1 실행
thread1 완료
thread2 실행
카운터= 5
thread2 완료
thread1 실행
thread1 완료
thread2 실행
thread2 완전 종료
thread1 실행
thread1 완전 종료
프로그램 종료
]$
'컴퓨터 > 프로그래밍' 카테고리의 다른 글
C언어 소켓 생성 함수 socket() (0) | 2020.03.16 |
---|---|
C언어 세마포어 제어 함수 semctl() (0) | 2020.03.16 |
C언어 세마포어 생성 및 접근 함수 semget() (0) | 2020.03.16 |