linux 프로세스 간 통신 공유 메모리 사용
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;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.