본문으로 바로가기

바다야크

  1. Home
  2. 컴퓨터/프로그래밍
  3. C언어 공유 메모리 정보 확인·변경·제거 함수 shmctl()

C언어 공유 메모리 정보 확인·변경·제거 함수 shmctl()

· 댓글개 · 바다야크

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 완전 종료
프로그램 종료
]$
SNS 공유하기
💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.