linux 프로세스 간 통신 공유 메모리 사용

공유 메모리는 프로세스 간 통신에서 가장 간단한 방식 중의 하나다.공유 메모리는 두 개 이상의 프로세스가 같은 메모리에 접근할 수 있도록 합니다.malloc () 함수가 다른 프로세스에 같은 물리적 메모리 영역을 가리키는 바늘을 되돌려주는 것과 같습니다.하나의 프로세스가 이 주소의 내용을 바꾸었을 때, 다른 프로세스는 이 변경 사항을 알아차릴 것이다.
shmget 함수 원형
shmget (공유 메모리 식별자를 얻거나 공유 메모리 대상을 만듭니다)
필요한 헤더 파일
#include
#include
함수 설명
공유 메모리 식별자를 얻거나 공유 메모리 대상을 만들고 공유 메모리 식별자를 되돌려줍니다
함수 원형
int shmget(key_t key, size_t size, int shmflg)
함수 입력 값
key
0(IPC PRIVATE): 새 공유 메모리 객체가 설정됩니다.
0보다 큰 32비트 정수: 동작을 확인하기 위해shmflg의 매개 변수를 보십시오.일반적으로 이 값은 ftok에서 반환된 IPC 키 값에서 파생되어야 합니다.
size
0보다 큰 정수: 새 공유 메모리 크기(바이트)
0: 공유 메모리만 가져올 때 0으로 지정
shmflg
0: 공유 메모리 식별자를 찾습니다. 존재하지 않으면 함수가 잘못됩니다
IPC_CREAT:shmflg & IPCCREAT가 진짜일 때 키 값과 키가 같은 공유 메모리가 존재하지 않으면 공유 메모리를 새로 만듭니다.만약 이러한 공유 메모리가 존재한다면 이 공유 메모리의 표식자를 되돌려줍니다
IPC_CREAT|IPC_EXCL: 키 값이 키와 같은 공유 메모리가 핵에 존재하지 않으면 공유 메모리를 새로 만듭니다.만약 이러한 공유 메모리가 존재한다면 오류 보고
함수 반환값
성공: 공유 메모리의 식별자를 되돌려줍니다
오류: 1, 오류 원인은 error에 저장됩니다
추가 설명
상기shmflg 파라미터는 패턴 로고 파라미터로 사용 시 IPC 대상의 접근 권한(예를 들어 0600)과 |연산을 통해 신호 집합의 접근 권한을 확정해야 한다
오류 코드
EINVAL: 매개변수 크기가 SHMMIN보다 작거나 SHMMAX보다 큽니다.
EEXIST: 키가 가리키는 공유 메모리를 미리 만들지만 이미 존재합니다
EIDRM: 매개변수 키가 가리키는 공유 메모리가 삭제됨
ENOSPC: 시스템에서 허용되는 최대 공유 메모리(SHMALL) 초과
ENOENT: 매개변수 키가 가리키는 공유 메모리가 존재하지 않으며 shmflg 매개변수에 IPC 가 설치되어 있지 않습니다.CREAT 비트
EACCES: 권한 없음
ENOMEM: 코어 메모리 부족
shmat
shmat (공유 메모리 영역의 대상을 호출 프로세스의 주소 공간에 비추기)
필요한 헤더 파일
#include
#include
함수 설명
공유 메모리 식별자가shmid인 공유 메모리를 연결하고 연결이 성공한 후 공유 메모리 영역의 대상을 호출 프로세스의 주소 공간에 비추어 로컬 공간처럼 접근할 수 있습니다
함수 원형
void *shmat(int shmid, const void *shmaddr, int shmflg)
함수 입력 값
shmid
공유 메모리 식별자
shmaddr
공유 메모리가 프로세스 메모리 주소에 나타날 위치를 지정하고, NULL로 직접 지정하여 커널에서 적당한 주소 위치를 결정합니다
shmflg
SHM_RDONLY: 읽기 전용 모드, 기타 읽기 및 쓰기 모드
함수 반환값
성공: 공유 메모리 주소 추가
오류: 1, 오류 원인은 error에 저장됩니다
추가 설명
fork 후 하위 프로세스는 연결된 공유 메모리 주소를 계승합니다.exec 이후 이 하위 프로세스는 연결된 공유 메모리 주소와 자동으로 분리됩니다 (detach).프로세스가 끝나면 연결된 공유 메모리 주소가 자동으로 분리됩니다 (detach)
오류 코드
EACCES: 공유 메모리를 지정된 방식으로 연결할 수 있는 권한이 없습니다.
EINVAL: 잘못된 매개 변수 shmid 또는 shmaddr
ENOMEM: 코어 메모리 부족
shmdt 함수 원형
shmdt (공유 메모리 연결 끊기)
필요한 헤더 파일
#include
#include
함수 설명
shmat 함수와 반대로 공유 메모리의 추가점을 끊는 주소입니다. 이 프로세스가 이 공유 메모리에 접근하는 것을 금지합니다.
함수 원형
int shmdt(const void *shmaddr)
함수 입력 값
shmaddr: 연결된 공유 메모리의 시작 주소
함수 반환값
성공: 0
오류: 1, 오류 원인은 error에 저장됩니다
추가 설명
이 함수 호출은 지정한 공유 메모리 영역을 삭제하지 않고, 이전에shmat 함수로 연결된 공유 메모리 (attach) 를 현재 프로세스에서 분리합니다.
오류 코드
EINVAL: 잘못된 매개 변수 shmaddr
shmctl 함수 원형
shmctl(공유 메모리 관리)
필요한 헤더 파일
#include
#include
함수 설명
공유 메모리 제어 완료
함수 원형
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
함수 입력 값
shmid
공유 메모리 식별자
cmd
IPC_STAT: 공유 메모리의 상태를 받아 공유 메모리의shmidds 구조가 buf로 복사됨
IPC_SET: 공유 메모리의 상태를 변경하고 buf가 가리키는 shmidds 구조의 uid,gid,mode를 공유 메모리로 복사하는shmidds 구조 내
IPC_RMID: 이 공유 메모리 삭제
buf
공유 메모리 관리 구조체.구체적인 설명은 공유 메모리 핵 구조 정의 부분 참조
함수 반환값
성공: 0
오류: 1, 오류 원인은 error에 저장됩니다
오류 코드
EACCESS: 매개변수 cmd는 IPCSTAT, 공유 메모리를 읽을 수 있는 권한이 없음
EFAULT: 잘못된 메모리 주소를 가리키는 매개변수 buf
EIDRM: shmid로 식별된 공유 메모리가 삭제됨
EINVAL: 잘못된 매개 변수 cmd 또는 shmid
EPERM: 매개변수 cmd는 IPCSET 또는 IPCRMID를 실행할 수 있는 권한이 없습니다.
두 프로세스, 하나는 읽기 프로세스, 하나는 쓰기 프로세스.프로세스 간에 신호량을 통해 동기화를 유지하고 프로세스 간의 데이터 전송은 공유 메모리를 사용한다.
먼저 쓰기 프로세스를 시작하고 공유 메모리를 설정하며 신호량을 설정하고 공유 메모리에 데이터를 씁니다.이후 방출 신호량.읽기 프로세스가 공유 메모리를 연결하여 신호량을 얻고 공유 메모리의 내용을 읽은 후에 신호량을 방출합니다.
프로세스 컨텐트 쓰기
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#include <sys/sem.h>
#include "Ccommon.h"
union semun
{
 int val;
 struct semid_ds *buf;
 unsigned short *array;
};
//      
static int set_semvalue(void);
//     
static void del_semvalue(void);
//     
static int semaphore_p(void);
//     
static int semaphore_v(void);
static int sem_id;
int main()
{
  bool isRuning = true;
  void *pMem = NULL;
  struct shared_use_str *pshared_use_str;
  char buffer[BUFSIZ];
  int ishmid;
                   
  //     
   sem_id = semget((key_t)1234,1,0666|IPC_CREAT);
  //      
 ishmid = shmget((key_t)1234,sizeof(struct shared_use_str),0666|IPC_CREAT );
                   
   //      
   if(!set_semvalue())
   {
     fprintf(stderr,"Failed to initialize semaphore
"); exit(-1); } if(-1 == ishmid) { printf("shmid failed
"); exit(-1); } // pMem = shmat(ishmid,(void *)0,0); if(pMem == (void *)-1) { printf("shmat failed
"); exit(-1); } printf("Memory Attached at %X
",pMem); // pshared_use_str = (struct shared_use_str *) pMem; while(true == isRuning) { // if(!semaphore_p()) { printf("semp p failed
"); exit(-1); } printf("enter some text
"); fgets(buffer,BUFSIZ,stdin); // strncpy(pshared_use_str->somedate,buffer,TEXT_SIZE); pshared_use_str->iwrite_by_you = 1; if(strncmp(buffer,"end",3) == 0) { isRuning = 0; } // if(!semaphore_v()) { printf("failed to set v
"); exit(-1); } } // sleep(3); // del_semvalue(); // if(shmdt(pMem) == -1) { printf("shmdt failed
"); return -1; } return 0; } static int set_semvalue(void) { union semun sem_unition; sem_unition.val = 1; // , 1 if(semctl(sem_id,0,SETVAL,sem_unition) == -1) { printf("faile to semctl
"); return -1; } return 1; } static void del_semvalue(void ) { union semun sem_unition; // if(semctl(sem_id,0,IPC_RMID,sem_unition) == -1) { printf("failed to semctl
"); return; } } static int semaphore_p(void ) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; // , 1 , 0 。 if(-1 == semop(sem_id,&sem_b,1)) { printf("semaphore failed
"); return 0; } return 1; } static int semaphore_v(void ) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; // , 1 , 0 。 if(-1 == semop(sem_id,&sem_b,1)) { printf("semaphore failed
"); return 0; } return 1; }

독자 진행 과정
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#include "Ccommon.h"
#include <sys/sem.h>
union semun
{
 int val;
 struct semid_ds *buf;
 unsigned short *array;
};
//      
static int set_semvalue(void);
//     
static void del_semvalue(void);
//     
static int semaphore_p(void);
//     
static int semaphore_v(void);
static int sem_id;
int main()
{
  bool isRuning = true;
  void *pMem = NULL;
  struct shared_use_str *pshared_use_str;
  int ishmid;
    
    //     
   sem_id = semget((key_t)1234,1,0666|IPC_CREAT);
   //      
  ishmid = shmget((key_t)1234,sizeof(struct shared_use_str),0666|IPC_CREAT);
    
  if(-1 == ishmid)
  {
      printf("shmid failed
"); exit(-1); } // pMem = shmat(ishmid,(void *)0,0); if(pMem == (void *)-1) { printf("shmat failed
"); exit(-1); } printf("Memory Attached at %X
",pMem); pshared_use_str = (struct shared_use_str *) pMem; pshared_use_str->iwrite_by_you = 0; while(true == isRuning) { // if(!semaphore_p()) { printf("semp p failed
"); exit(-1); } printf("you write %s
",pshared_use_str->somedate); sleep(rand()%5); pshared_use_str->iwrite_by_you = 0; if(strncmp(pshared_use_str->somedate,"end",3) == 0) { isRuning = false; } if(!semaphore_v()) { printf("failed to set v
"); exit(-1); } } // if(shmdt(pMem) == -1) { printf("shmdt failed
"); exit(-1); } // if(shmctl(ishmid,IPC_RMID,0) == -1) { printf("shmctl failed
"); exit(-1); } return 0; } static void del_semvalue(void ) { union semun sem_unition; // if(semctl(sem_id,0,IPC_RMID,sem_unition) == -1) { printf("failed to semctl
"); return; } } static int semaphore_p(void ) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; // , 1 , 0 。 if(-1 == semop(sem_id,&sem_b,1)) { printf("semaphore failed
"); return 0; } return 1; } static int semaphore_v(void ) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; // , 1 , 0 。 if(-1 == semop(sem_id,&sem_b,1)) { printf("semaphore failed
"); return 0; } return 1; }

좋은 웹페이지 즐겨찾기