🌷 C 프로그래밍을 통한 공유 메모리 & 메시지 큐 사용 프로세스 구현 # 2
# 구현할 프로그램 개요
프로그램 번호 | 프로그램 1 | 프로그램 2 | 프로그램 3 |
수행 작업 | 1초 간격으로 1~10까지 값을 공유 메모리에 차례로 입력 |
루프를 돌며 공유 메모리 값을 읽어와 메시지 큐에 입력 |
루프를 돌며 대기 후 메시지 큐에 입력된 값 중 짝수만을 읽어와 출력 |
💮 C 언어를 통한 프로그램 # 2 구현
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#define SHM_KEY 1234
#define MSG_KEY 5678
// 공유 메모리 구조체 정의
struct SharedMemory {
ㅤㅤint value;
};
// 메시지 큐 구조체 정의
struct Message {
ㅤㅤlong mtype;
ㅤㅤint data;
};
int main() {
ㅤㅤ// 공유 메모리 연결
ㅤㅤint shmid = shmget(SHM_KEY, sizeof(struct SharedMemory), 0666);
ㅤㅤif (shmid == -1) {
ㅤㅤㅤㅤperror("shmget");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
ㅤㅤstruct SharedMemory *shm = (struct SharedMemory *)shmat(shmid, NULL, 0);
ㅤㅤif (shm == (struct SharedMemory *)(-1)) {
ㅤㅤㅤㅤperror("shmat");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
ㅤㅤ// 메시지 큐 생성
ㅤㅤint msqid = msgget(MSG_KEY, 0666 | IPC_CREAT);
ㅤㅤif (msqid == -1) {
ㅤㅤㅤㅤperror("msgget");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
ㅤㅤprintf("Program 2 is running...\n");
ㅤㅤstruct Message message;
ㅤㅤwhile (1) {
ㅤㅤㅤㅤif (shm->value != 0) {
ㅤㅤㅤㅤㅤㅤmessage.mtype = 1; // 메시지 타입 1
ㅤㅤㅤㅤㅤㅤmessage.data = shm->value;
ㅤㅤㅤㅤㅤㅤmsgsnd(msqid, &message, sizeof(int), 0);
ㅤㅤㅤㅤㅤㅤprintf("Program 2 sent to message queue: %d\n", message.data);
ㅤㅤㅤㅤㅤㅤshm->value = 0; // 공유 메모리 초기화
ㅤㅤㅤㅤ}
ㅤㅤ}
ㅤㅤ// 공유 메모리 및 메시지 큐 삭제하지 않음
ㅤㅤreturn 0;
}
1. 프로그램 실행에 필요한 라이브러리 include
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
++ 각 Include 문 상세 설명
include 문 | 역할 |
stdio.h | 표준 입출력 함수를 포함하는 헤더 파일 |
stdlib.h | C 프로그래밍 언어에서 기본적인 유틸리티 함수들을 포함하는 헤더 파일 |
unistd.h | 유닉스 및 리눅스 시스템에서 제공하는 시스템 호출을 포함하는 헤더 파일 |
sys/types.h | 시스템 데이터 형식을 정의하는 헤더 파일 |
sys/ipc.h | IPC(Inter-Process Communication) 기능을 사용하기 위해 필요한 헤더 파일 |
sys/shm.h | 공유 메모리 세그먼트 제어 시 사용되는 헤더 파일 |
sys/msg.h | 시스템 V IPC 메시지 큐를 다루기 위한 헤더 파일 |
2. 공유 메모리를 식별하는 데 사용될 키 정의
#define SHM_KEY 1234
#define MSG_KEY 5678
3. 공유 메모리에 저장될 데이터 구조 정의
struct SharedMemory {
ㅤㅤint value;
};
4. 메시지 큐 구조체 정의
// 메시지 큐 구조체 정의
struct Message {
ㅤㅤlong mtype;
ㅤㅤint data;
};
++ 구조체 필드 설명
mtype | data |
메시지 큐에서 메시지를 수신할 때 메시지의 유형 지정 | 메시지에 관련된 정수형 데이터 저장 |
5. main() 함수에서 공유 메모리 연결
int main() {
ㅤㅤ// 공유 메모리 연결
ㅤㅤint shmid = shmget(SHM_KEY, sizeof(struct SharedMemory), 0666);
ㅤㅤif (shmid == -1) {
ㅤㅤㅤㅤperror("shmget");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
++ 코드 설명 상세
코드 | 설명 |
shmget() | 공유 메모리 세그먼트 생성 & 참조하기 위한 함수 |
SHM_KEY | 공유 메모리 세그먼트 식별 |
sizeof(struct SharedMemory) | 필요한 메모리 크기 정의 |
0666 | 퍼미션 설정용 매개변수 |
shmid == -1 | shmget() 의 작업 실패 시 -1 반환 |
perror() | 오류 메시지 출력용 함수 |
exit(1) | exit() 을 호출하여 프로그램 종료 |
6. 공유 메모리를 현재 프로세스의 주소 공간에 첨부
struct SharedMemory *shm = (struct SharedMemory *)shmat(shmid, NULL, 0);
ㅤㅤif (shm == (struct SharedMemory *)(-1)) {
ㅤㅤㅤㅤperror("shmat");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
+ 코드 설명 상세
코드 | 설명 |
shmat(shmid, NULL, 0) | 공유 메모리 세그먼트를 프로세스의 주소 공간에 첨부 |
shm == (struct SharedMemory *)(-1) | shmget() 의 작업 실패 시 -1 반환 |
perror("shmat") | 오류 메시지 출력용 함수 |
exit(1) | exit() 을 호출하여 프로그램 종료 |
++ 인자값 설명 상세
인자 | 설명 |
shmid | 공유 메모리 식별자 |
NULL | 메모리 세그먼트 주소 자동 선택 |
0 | 첨부 수행하는 플래그 매개변수 |
7. 메시지 큐 생성
// 메시지 큐 생성
ㅤㅤint msqid = msgget(MSG_KEY, 0666 | IPC_CREAT);
ㅤㅤif (msqid == -1) {
ㅤㅤㅤㅤperror("msgget");
ㅤㅤㅤㅤexit(1);
ㅤㅤ}
++ 코드 설명 상세
코드 | 설명 |
int msqid = msgget() | 메시지 큐 식별자를 얻기 위해 사용되는 함수 |
MSG_KEY | 메시지 큐 식별 |
0666 | IPC_CREAT | 권한 지정 + 메시지 큐가 없는 경우 새로 생성하도록 하는 플래그 |
8. 공유 메모리 검사 후 메시지 큐에 값 전송
printf("Program 2 is running...\n");
ㅤㅤstruct Message message;
ㅤㅤwhile (1) {
ㅤㅤㅤㅤif (shm->value != 0) {
ㅤㅤㅤㅤㅤㅤmessage.mtype = 1; // 메시지 타입 1
ㅤㅤㅤㅤㅤㅤmessage.data = shm->value;
ㅤㅤㅤㅤㅤㅤmsgsnd(msqid, &message, sizeof(int), 0);
ㅤㅤㅤㅤㅤㅤprintf("Program 2 sent to message queue: %d\n", message.data);
ㅤㅤㅤㅤㅤㅤshm->value = 0; // 공유 메모리 초기화
ㅤㅤㅤㅤ}
ㅤㅤ}
++ 코드 설명 상세
코드 | 설명 |
struct Message message | Message 구조체를 인스턴스화하여 새 메시지 생성 |
message.mtype = 1 | 메시지의 유형을 1로 설정 (공유 메모리의 값이 0이 아닐 경우) |
message.data = shm->value | 메시지의 데이터를 공유 메모리의 값으로 설정 |
msgsnd() | 메시지 큐에 메시지 전송 |
sizeof(int) | 전송할 데이터의 크기를 나타내는 매개변수 |
shm->value = 0 | 공유 메모리의 값을 0으로 초기화 |
9. 프로그램 종료 후 공유 메모리 & 메시지 큐를 보존한 상태로 리턴
ㅤㅤ// 공유 메모리 및 메시지 큐 삭제하지 않음
ㅤㅤreturn 0;
}
'✒️ Linux Programming > with Oracle Virtual Box & Ubuntu' 카테고리의 다른 글
[Oracle Virtual Box] 화면 해상도 조정을 통한 Oracle Virtual Box 화면 크기 변경 (0) | 2023.10.13 |
---|---|
[Linux & Ubuntu] C 프로그래밍을 통한 공유 메모리 & 메시지 큐 사용 프로세스 구현 #3 (0) | 2023.10.11 |
[Linux & Ubuntu] C 프로그래밍을 통한 공유 메모리 & 메시지 큐 사용 프로세스 구현 #1 (0) | 2023.10.05 |
[Linux & Oracle Virtual Box] 오라클 버츄얼 박스(Oracle Virtual Box) 설치 및 환경설정 방법 (0) | 2023.09.07 |
[Linux & Ubuntu] 우분투(Ubuntu) 설치 및 환경 설정 (0) | 2023.09.05 |