C shmctl() 공유 메모리 정보 확인·변경·제거 함수
shmctl() 함수는 공유 메모리에 대한 정보를 구하거나 변경 또는 제거합니다.
- 헤더: sys/ipc.h, sys/shm.h
- 형태: int shmctl(int shmid, int cmd, struct shmid_ds *buf)
- 인수: int shmid 공유 메모리 식별 번호
int 제어 명령
struct shmid_ds *buf 공유 메모리 정보 구하기 위한 버퍼 포인터 - 반환: int 0 == 성공, -1 == 실패
struct shmid_ds 구조
3번째 인수 struct shmid_ds 구조는 아래와 같습니다.
struct shmid_ds {
struct ipc_perm shm_perm; /* 접근권한 */
int shm_segsz; /* 세그먼트의 크기(bytes) */
time_t shm_atime; /* 마지막 접근 시간 */
time_t shm_dtime; /* 마지막 제거 시간 */
time_t shm_ctime; /* 마지막 변경 시간 */
unsigned short shm_cpid; /* 생성자의 프로세스의 프로세스 id */
unsigned short shm_lpid; /* 마지막으로 작동한 프로세스의 프로세스 pid */
short shm_nattch; /* 현재 접근한 프로세스의 수 */
/* 다음은 개별적이다 */
unsigned short shm_npages; /* 세그먼트의 크기(pages) */
unsigned long *shm_pages;
struct shm_desc *attaches; /* 접근을 위한 기술자들 */
};
shm_perm 멤버의 필드들은 아래와 같이 설정할 수 있습니다.
shm_perm 멤버의 필드들은 아래와 같이 설정할 수 있습니다.
struct ipc_perm{
key_t key;
ushort uid; /* owner의 euid 와 egid */
ushort gid;
ushort cuid; /* 생성자의 euid 와 egid */
ushort cgid;
ushort mode; /* 접근 모드의 하위 9 bits */
ushort seq; /* 연속 수(sequence number) */
};
C언어 shmctl() 함수 예제
예제에서는 두개의 쓰레드를 만들어 첫번째 쓰레드는 카운터 값을 증가 시키고 두번째 쓰레드는 카운터를 화면에 출력합니다. 카운터가 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언어 shmctl() 예제 실행 결과
]$ 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언어 세마포어 생성 및 접근 함수 semget() (0) | 2020.03.16 |
---|---|
C언어 공유 메모리를 프로세스에서 분리 함수 shmdt() (0) | 2020.03.16 |
C언어 공유 메모리를 프로세스에 첨부 함수 shmat() (0) | 2020.03.16 |