😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ 닀쀑 처리] ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신 (IPC) with μœ λ‹‰μŠ€ μ‹œμŠ€ν…œ V/XSI (λ©”μ‹œμ§€ 큐, μ„Έλ§ˆν¬μ–΄, 곡유 λ©”λͺ¨λ¦¬) λ³Έλ¬Έ

πŸ‘©‍πŸ’» IoT (Embedded)/Raspberry Pi

[ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ 닀쀑 처리] ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신 (IPC) with μœ λ‹‰μŠ€ μ‹œμŠ€ν…œ V/XSI (λ©”μ‹œμ§€ 큐, μ„Έλ§ˆν¬μ–΄, 곡유 λ©”λͺ¨λ¦¬)

μ§•μ§•μ•ŒνŒŒμΉ΄ 2024. 1. 12. 18:36
728x90
λ°˜μ‘ν˜•

<μ„œμ˜μ§„ λ‹˜μ˜ 사물인터넷을 μœ„ν•œ λ¦¬λˆ…μŠ€ ν”„λ‘œκ·Έλž˜λ° with λΌμ¦ˆλ² λ¦¬νŒŒμ΄ μ„œμ μ„ μ°Έκ³ ν•΄μ„œ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€ :-)>

 

⭐ μœ λ‹‰μŠ€ μ‹œμŠ€ν…œ V

AT&T 벨 μ—°κ΅¬μ†Œμ—μ„œ λ§Œλ“€λ˜ μœ λ‹‰μŠ€ 계열을 톡칭함

ν˜„μž¬ λ¦¬λˆ…μŠ€λŠ” μœ λ‹‰μŠ€ μ‹œμŠ€ν…œ V κ³„μ—΄μ˜ μœ λ‹‰μŠ€μ—μ„œ μ œκ³΅ν•˜λŠ” μ‹œμŠ€ν…œ 호좜과 BSD κ³„μ—΄μ˜ μœ λ‹‰μŠ€μ—μ„œ μ œκ³΅ν•˜λ˜ μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ λͺ¨λ‘ μ œκ³΅ν•œλ‹€

 

μ‹œμŠ€ν…œ V의 IPC λŠ” POSIX IPC κ°€ λ“±μž₯ν•œ μ΄ν›„λ‘œ XSI (X System Interface) 둜 뢈리우고 μžˆλ‹€

ꡬ뢄 λ‚΄μš©
λ©”μ‹œμ§€ 큐 (Message Queue) λ©”μ‹œμ§€ λ‹¨μœ„λ‘œ I/O λ₯Ό μˆ˜ν–‰ν•˜λŠ”λ°, λ‹€λ₯Έ IPC 와 달리 μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈκ°€ 같은 μ‹œκ°„μ— μ‘΄μž¬ν•  ν•„μš”κ°€ μ—†λ‹€
μ„Έλ§ˆν¬μ–΄ (Semaphore) 데이터 전솑을 λͺ©μ μœΌλ‘œ λ§Œλ“€μ–΄μ§„ IPC κ°€ μ•„λ‹Œ ν”„λ‘œμ„ΈμŠ€ 동기화에 ν•„μš”ν•œ 곡유 λ³€μˆ˜μ™€ 같은 곡유된 λ¦¬μ†ŒμŠ€ μ œν•œμ„ μœ„ν•œ μ„Έλ§ˆν¬μ–΄μ˜ 참쑰와 쑰직을 μœ„ν•΄ λ§Œλ“€μ–΄μ§„ IPC
곡유 λ©”λͺ¨λ¦¬ (Shared Memory) λͺ¨λ“  IPC λŠ” λΉˆλ²ˆν•œ λ©”λͺ¨λ¦¬ λ³΅μ‚¬λ‘œ μΈν•œ μ„±λŠ₯ λ¬Έμ œκ°€ μ œκΈ°λ˜λŠ”λ°, 곡유 λ©”λͺ¨λ¦¬λŠ” 컀널과 ν”„λ‘œμ„ΈμŠ€ 사이에 λ©”λͺ¨λ¦¬ 볡사λ₯Ό 2회 μ€„μž„μœΌλ‘œμ¨ λΉ„μ•½μ μœΌλ‘œ IPC μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€
곡유 λ©”λͺ¨λ¦¬μ—λŠ” μ„Έλ§ˆν¬μ–΄ 같은 동기화 λ©”μ»€λ‹ˆμ¦˜μ΄ λ³„λ„λ‘œ μš”κ΅¬λœλ‹€

 

β˜‘οΈ λ©”μ‹œμ§€ 큐

μœ λ‹‰μŠ€  μ‹œμŠ€ν…œ V의 ν”„λ‘œμ„ΈμŠ€ μ‚¬μ΄μ—μ„œ μ„œλ‘œ 톡신을 ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” λ©”μ»€λ‹ˆμ¦˜

μž…μΆœλ ₯ 데이터λ₯Ό 컀널 내뢀에 λ©”μ‹œμ§€ 리슀트 ν˜•νƒœλ‘œ λ³΄κ΄€ν•˜λŠ”λ°, λ©”μ‹œμ§€ νƒ€μž…μ€ μ„ νƒμ μœΌλ‘œ λ©”μ‹œμ§€μ˜ 검색이 κ°€λŠ₯ν•˜λ‹€

FIFO 와 λΉ„μŠ·ν•˜μ§€λ§Œ λ©”μ‹œμ§€λŠ” 쀑간에 μ €μž₯이 되기 λ•Œλ¬Έμ— λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ” ν”„λ‘œμ„ΈμŠ€μ™€ λ©”μ‹œμ§€λ₯Ό λ°›λŠ” ν”„λ‘œμ„ΈμŠ€κ°€ λ™μΌν•œ μ‹œμ μ— 주고받을 ν•„μš”κ°€ μ—†λ‹€

 

λ©”μ‹œμ§€ νμ—μ„œλŠ” msqid_ds ꡬ쑰체λ₯Ό μ‚¬μš©ν•˜λ©°, ν˜ΈμΆœμ— μ‹€νŒ¨ν•˜λ©΄ -1을 λ°˜ν™˜ν•œλ‹€

λ©”μ‹œμ§€ 큐λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν˜„μž¬ λ©”μ‹œμ§€λ₯Ό 주고받을 수 μžˆλŠ” 채널이 ν•„μš”ν•œλ° msgget() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ νšλ“, ν˜ΈμΆœμ— μ„±κ³΅ν•˜λ©΄ μ±„λ„μ˜ ID κ°€ λ°˜ν™˜λœλ‹€

 

λ©”μ‹œμ§€ 큐에 λŒ€ν•œ 채널을 νšλ“ν•œ ν›„μ—λŠ” 데이터λ₯Ό μ£Όκ³ λ°›μ•„μ•Ό ν•˜λŠ”λ°,

λ©”μ‹œμ§€ λ³΄λ‚΄λŠ” msgsnd() ν•¨μˆ˜ ν˜ΈμΆœμ— μ„±κ³΅ν•˜λ©΄ 0 λ°˜ν™˜

λ©”μ‹œμ§€ λ°›λŠ” msgrcv() ν•¨μˆ˜ ν˜ΈμΆœμ— μ„±κ³΅ν•˜λ©΄ 읽은 λ°μ΄ν„°μ˜ λ°”μ΄νŠΈ μˆ˜κ°€ λ°˜ν™˜λœλ‹€

데이터 μ£Όκ³  λ°›λŠ” msgbuf ꡬ쑰체

채널을 μ œμ–΄ν•˜κ±°λ‚˜ μ‚­μ œν•˜λŠ” msgctl() ν•¨μˆ˜

// λ©”μ‹œμ§€ 큐λ₯Ό μ΄μš©ν•œ 톡신 server
// μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈλŠ” λ™μΌν•œ ν‚€ κ°’ κ°€μ Έμ•Ό ν•œλ‹€ (51234 둜 섀정함)
#include <stdio.h>
#include <unistd.h>
#include <sys/msg.h>

#define MSQKEY 51234

struct msgbuf {
    long mtype; /* λ©”μ‹œμ§€μ˜ νƒ€μž… : 0 μ΄μƒμ˜ μ •μˆ«κ°’ */
    char mtext[BUFSIZ]; /* λ©”μ‹œμ§€μ˜ λ‚΄μš© : 1λ°”μ΄νŠΈ μ΄μƒμ˜ λ¬Έμžμ—΄ */
};

int main(int argc, char **argv)
{
    key_t key;
    int n, msqid;
    struct msgbuf mb;
    key = MSQKEY;

    /* λ©”μ‹œμ§€ 큐의 채널을 μƒμ„±ν•œλ‹€. */
    if((msqid = msgget(key, IPC_CREAT | IPC_EXCL | 0666)) < 0) {
        perror("msgget()");
        return -1;
    }

    /* λ©”μ‹œμ§€ νμ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜¨λ‹€. */
    while((n = msgrcv(msqid, &mb, sizeof(mb), 0, 0)) > 0) {
        switch (mb.mtype) {
            /* λ©”μ‹œμ§€ νƒ€μž…(mtype)이 1이면 화면에 κ°€μ Έμ˜¨ 데이터λ₯Ό 좜λ ₯ν•œλ‹€. */
            case 1:
                write(1, mb.mtext, n);
                break;
            /* λ©”μ‹œμ§€ νƒ€μž…(mtype)이 2이면 λ©”μ‹œμ§€ 큐의 채널을 μ‚­μ œν•œλ‹€. */
            case 2:
                if(msgctl(msqid, IPC_RMID, (struct msqid_ds *) 0) < 0) {
                    perror("msgctl()");
                    return -1;
                }
                break;
        }
    }

    return 0;
}

/*
μ„œλ²„λŠ” λ©”μ‹œμ§€ 큐λ₯Ό μœ„ν•œ 채널을 μƒμ„±ν•˜κ³  λ©”μ‹œμ§€ νλ‘œλΆ€ν„° 데이터λ₯Ό κ°€μ Έμ™€μ„œ mtype 값이 1이면 화면에 κ°€μ Έμ˜¨ 데이터 좜λ ₯
mtype 값이 2이면 λ©”μ‹œμ§€ 큐에 λŒ€ν•œ 채널을 μ‚­μ œν•œλ‹€

@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ gcc -o msg_server msg_server.c
@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ ./msg_server &
*/
// λ©”μ‹œμ§€ 큐λ₯Ό μ΄μš©ν•œ 톡신 client
// μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈλŠ” λ™μΌν•œ ν‚€ κ°’ κ°€μ Έμ•Ό ν•œλ‹€ (51234 둜 섀정함)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/msg.h>

#define MSQKEY 51234

struct msgbuf {
    long mtype;
    char mtext[BUFSIZ];
};

int main(int argc, char **argv)
{
    key_t key;
    int rc, msqid;
    char* msg_text = "hello world\n";

    struct msgbuf *mb;
    mb = (struct msgbuf*)malloc(sizeof(struct msgbuf) + strlen(msg_text));

    key = MSQKEY;
    if((msqid = msgget(key, 0666)) < 0) { 		/* λ©”μ‹œμ§€ 큐의 채널을 κ°€μ Έμ˜¨λ‹€. */
        perror("msgget()");
        return -1;
    }

    /* mtype을 1둜 μ„€μ •ν•˜κ³  hello worldλΌλŠ” λ¬Έμžμ—΄μ„ 보낸닀. */
    mb->mtype = 1;
    strcpy(mb->mtext, msg_text);
    rc = msgsnd(msqid, mb, strlen(msg_text)+1, 0); 	/* λ©”μ‹œμ§€ 큐둜 데이터λ₯Ό 보낸닀. */
    if(rc == -1) {
        perror("msgsnd()");
        return -1;
    }

    /* mtype을 2둜 μ„€μ •ν•˜κ³  보낸닀. */
    mb->mtype = 2;
    memset(mb->mtext, 0, sizeof(mb->mtext));
    if(msgsnd(msqid, mb, sizeof(mb->mtext), 0) < 0) {
        perror("msgsnd()");
        return -1;
    }

    return 0;
}

/*
ν΄λΌμ΄μ–ΈνŠΈλŠ” mtype 을 1둜 μ„€μ •ν•˜κ³  λ¬Έμžμ—΄μ„ μ„œλ²„λ‘œ 보내고
λ‹€μ‹œ mtype 을 2둜 μ„€μ •ν•˜κ³  μ„œλ²„λ‘œ λ©”μ‹œμ§€λ₯Ό 보낸닀

@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ gcc -o msg_client msg_client.c
@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ ./msg_client 
*/
gcc -o msg_server msg_server.c
./msg_server &

gcc -o msg_client msg_client.c
./msg_client

 

β˜‘οΈ IPC κ΄€λ ¨ λͺ…λ Ήμ–΄

μœ λ‹‰μŠ€ μ‹œμŠ€ν…œ v의 μ„€μ •λœ IPC 채널을 ν™•μΈν•˜κ³  싢은 κ²½μš°μ—λŠ” ipcs λͺ…렁어 μ‚¬μš©ν•œλ‹€

-q : λ©”μ‹œμ§€ 큐

-s : μ„Έλ§ˆν¬μ–΄

-m : 곡유 λ©”λͺ¨λ¦¬

ipcs [-q | -m | -s]

 

채널을 μƒμ„±ν•˜κ³  싢은 경우

ipcmk [-M size] [-S nsems] [-Q] [-p mode]

 

μ„€μ •λœ 채널을 μ‚­μ œν•˜κ³  싢은 경우

μ±„λ„μ˜ ID λ‚˜ μ±„λ„μ˜ ν‚€ μ΄μš©ν•΄μ„œ μ‚­μ œν•  수 있음

ipcrm [-q | -m | -s { μ±„λ„μ˜_ID }+ ] [-Q | -M | -S] { μ±„λ„μ˜_Key }+ ]

 

λ©”μ‹œμ§€ν μ„œλ²„ μ‹€ν–‰ν•œ ν›„ ipcs λͺ…λ Ήμ–΄ μˆ˜ν–‰ν•˜λ©΄ 킀와 λ©”μ‹œμ§€ 큐의 ID κ°€ ν‘œμ‹œλœλ‹€

-q μ˜΅μ…˜κ³Ό λ©”μ‹œμ§€ 큐의 ID μ΄μš©ν•΄μ„œ ν•΄λ‹Ή 채널 μ‚­μ œν•  수 μžˆλ‹€

ipcs

ipcrm -q msqidμ μœΌμ…ˆ

 

β˜‘οΈ μ„Έλ§ˆν¬μ–΄ (Semaphore)

두 개의 μ›μžμ  ν•¨μˆ˜λ‘œ μ‘°μž‘λ˜λŠ” μ •μˆ˜ λ³€μˆ˜

닀쀑 ν”„λ‘œκ·Έλž˜λ° ν™˜κ²½μ—μ„œ 곡유 μžμ›μ— λŒ€ν•œ 접근을 μ œν•œν•˜λŠ” 방법

λ‹€μˆ˜μ˜ μžμ›μ„ 놓고 κ²½μŸν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ“€ μ‚¬μ΄μ—μ„œ ν•„μš”ν•œ 동기화 κΈ°λ²•μœΌλ‘œ μžμ›μ˜ 수λ₯Ό κΈ°λ‘ν•˜λŠ” μ„Έλ§ˆν¬μ–΄ λ³€μˆ˜μ™€ P (κ°μ†Œ), V (증가) 연산을 μ΄μš©ν•˜μ—¬ 동기화 ν•œλ‹€

 

μ„Έλ§ˆν¬μ–΄ 자료 κ΅¬μ‘°λŠ” semid_ds ꡬ쑰체

μ„Έλ§ˆν¬μ–΄λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ 채널 생성 semget() ν•¨μˆ˜ μˆ˜ν–‰ν•˜λ©°, μ„±κ³΅ν•˜λ©΄ μ±„λ„μ˜ ID λ°˜ν™˜λ˜κ³  μ‹€νŒ¨ν•˜λ©΄ -1

μ„Έλ§ˆν¬μ–΄λ₯Ό μ¦κ°€ν•˜κ±°λ‚˜ κ°μ†Œλ₯Ό ν•˜κΈ° μœ„ν•΄ semop() ν•¨μˆ˜ μˆ˜ν–‰ν•˜λ©°, μ„±κ³΅ν•˜λ©΄ 0 λ°˜ν™˜λ˜κ³  μ‹€νŒ¨ν•˜λ©΄ -1

μ„Έλ§ˆν¬μ–΄λ₯Ό μ„€μ •ν•  λ•Œ sembuf ꡬ쑰체 μ‚¬μš©

μ„Έλ§ˆν¬μ–΄λ₯Ό μ œμ–΄ν•˜κ±°λ‚˜ μ‚­μ œν•  λ•Œμ—λŠ” semctl() ν•¨μˆ˜

// μ„Έλ§ˆν¬μ–΄λ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•œ κ³Όμ •
// μ„Έλ§ˆν¬μ–΄μ˜ P μ—°μ‚°κ³Ό V 연산에 λŒ€ν•œ ν•¨μˆ˜
// 두 ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ„Έλ§ˆν¬μ–΄μ˜ λ™μž‘ μ•Œμ•„λ³΄κΈ°
#include <stdio.h>
#include <unistd.h>
#include <sys/sem.h>

int cnt = 0;
static int semid;

void p() 				/* μ„Έλ§ˆν¬μ–΄μ˜ P μ—°μ‚° */
{
    struct sembuf pbuf;
    pbuf.sem_num = 0;
    pbuf.sem_op = -1;
    pbuf.sem_flg = SEM_UNDO;

    if(semop(semid, &pbuf, 1) == -1) 	/* μ„Έλ§ˆν¬μ–΄μ˜ κ°μ†Œ 연산을 μˆ˜ν–‰ν•œλ‹€. */
        perror("p : semop()");
}

void v() 				/* μ„Έλ§ˆν¬μ–΄μ˜ V μ—°μ‚° */
{
    struct sembuf vbuf;
    vbuf.sem_num = 0;
    vbuf.sem_op = 1;
    vbuf.sem_flg = SEM_UNDO;

    if(semop(semid, &vbuf, 1) == -1) 	/* μ„Έλ§ˆν¬μ–΄μ˜ 증가 연산을 μˆ˜ν–‰ν•œλ‹€. */
        perror("v : semop()");
}

int main(int argc, char **argv)
{
    union semun { 			/* semun 곡용체 */
        int val;
        struct semid_ds *buf;
        unsigned short int *arrary;
    } arg;

    /* μ„Έλ§ˆν¬μ–΄μ— λŒ€ν•œ 채널 μ–»κΈ° */
    if((semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666)) == -1) {
        perror("semget()");
        return -1;
    }

    arg.val = 1; 			/* μ„Έλ§ˆν¬μ–΄ 값을 1둜 μ„€μ • */
    if(semctl(semid, 0, SETVAL, arg) == -1) {
        perror("semctl() : SETVAL");
        return -1;
    }

    while(1) {
        if(cnt >= 8) {
            cnt--;
            p();
            printf("decrease : %d\n", cnt);
            break;
        } else {
            cnt++;
            v();
            printf("increase : %d\n", cnt);
            usleep(100);
        }
    }

    /* μ„Έλ§ˆν¬μ–΄μ— λŒ€ν•œ 채널 μ‚­μ œ */
    if(semctl(semid, 0, IPC_RMID, arg) == -1) {
        perror("semctl() : IPC_RMID");
        return -1;
    }

    return 0;
}

/*
μ„Έλ§ˆν¬μ–΄λ₯Ό μœ„ν•œ 채널을 μƒμ„±ν•˜κ³  μ„Έλ§ˆν¬μ–΄ ν•œ 개λ₯Ό μƒμ„±ν•œλ‹€
μ½”λ“œ λ‚΄μ—μ„œ μ„Έλ§ˆν¬μ–΄μ— λŒ€ν•œ Pμ—°μ‚°κ³Ό V연산을 μˆ˜ν–‰ν•˜λŠ”λ°,
Vμ—°μ‚°μœΌλ‘œ μ„Έλ§ˆν¬μ–΄κ°€ μ¦κ°€λ˜κ³  λ‚œ 이후에 P연산을 톡해 κ°μ†Œλ  수 μžˆλ‹€

두 μ—°μ‚°μ˜ μ‹€ν–‰ μˆœμ„œλ₯Ό λ°”κΎΈλ©΄ Pμ—°μ‚°μ—μ„œλŠ” μ‚¬μš©ν•  수 μžˆλŠ” μ„Έλ§ˆν¬μ–΄κ°€ 생길 λ•ŒκΉŒμ§€ λŒ€κΈ°ν•œλ‹€
8κ°œκΉŒμ§€ μ„Έλ§ˆν¬μ–΄κ°€ μ¦κ°€ν•œ ν›„ λ‹€μ‹œ μ„Έλ§ˆν¬μ–΄κ°€ κ°μ†Œν•˜λŠ” 것을 확인할 수 μžˆλ‹€

@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ gcc -o sem sem.c
@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ ./sem
*/
gcc -o sem sem.c
./sem

 

β˜‘οΈ 곡유 λ©”λͺ¨λ¦¬

ν”„λ‘œμ„ΈμŠ€ 간에 λ©”λͺ¨λ¦¬λ₯Ό κ³΅μœ ν•˜λŠ” 방식

메리 볡사 횟수λ₯Ό μ€„μ—¬μ„œ μ„±λŠ₯ ν–₯상을 μ΄λˆλ‹€

μ—¬λŸ¬ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ λ™μ‹œμ— 같은 λ©”λͺ¨λ¦¬μ˜ μ£Όμ†Œλ‘œ μ ‘κ·Όν•  수 있기 λ•Œλ¬Έμ— μ„Έλ§ˆν¬μ–΄ 같은 동기화 기법이 ν•„μš”ν•˜λ‹€

λ¦¬λˆ…μŠ€μ—μ„œλŠ” 곡유 λ©”λͺ¨λ¦¬λ₯Ό μœ„ν•œ ν•¨μˆ˜λ“€μ„ μ œκ³΅ν•œλ‹€

곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” 곡유 λ©”λͺ¨λ¦¬μ— λŒ€ν•œ 채널을 μƒμ„±ν•˜κ±°λ‚˜ 기쑴의 채널을 가져와야 ν•œλ‹€

shmget() ν•¨μˆ˜λ‘œ μˆ˜ν–‰μ— μ„±κ³΅ν•˜λ©΄ ν•΄λ‹Ή 채널에 λŒ€ν•œ ID λ°˜ν™˜, μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ -1 λ°˜ν™˜

곡유 λ©”λͺ¨λ¦¬μ˜ μ‚¬μš©μ„ μœ„ν•΄μ„œλŠ” 곡유 λ©”λͺ¨λ¦¬λ₯Ό ν˜„μž¬ ν”„λ‘œμ„ΈμŠ€μ™€ μ—°κ²°ν•˜κ³  λ©”λͺ¨λ¦¬μ˜ μ‹œμž‘ μ£Όμ†Œλ₯Ό κ°€μ Έμ˜€λŠ”λ° shmat() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

μ‚¬μš©μ΄ λλ‚œ 곡유 λ©”λͺ¨λ¦¬λŠ” ν˜„μž¬μ˜ ν”„λ‘œμ„ΈμŠ€μ™€μ˜ 연결을 ν•΄μ œν•΄μ•Ό ν•˜λŠ”λ° shmdt() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

μ—°κ²°λœ 채널을 μ œμ–΄ν•˜κ±°λ‚˜ ν•΄μ œν•˜κ³  싢은 κ²½μš°μ—λŠ” shmctl() ν•¨μˆ˜μ΄λ©° μ„±κ³΅ν•˜λ©΄ 0, μ‹€νŒ¨ν•˜λ©΄ -1을 λ°˜ν™˜ν•œλ‹€

// 곡유 λ©”λͺ¨λ¦¬
// 2개의 ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§Œλ“€μ–΄μ„œ λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€μ™€ μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ 같은 λ©”λͺ¨λ¦¬ 곡간 μ‚¬μš©ν•˜κΈ°
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>

#define SHM_KEY 0x12345 		/* 곡유 λ©”λͺ¨λ¦¬λ₯Ό μœ„ν•œ ν‚€ */

int main(int argc, char **argv)
{
    int i, pid, shmid;
    int *cVal;
    void *shmmem = (void *)0;

    if((pid = fork()) == 0) { 		/* μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό μœ„ν•œ μ„€μ • */
        /* 곡유 λ©”λͺ¨λ¦¬ 곡간을 κ°€μ Έμ˜¨λ‹€. */
        shmid = shmget((key_t)SHM_KEY, sizeof(int), 0);
        if(shmid == -1) {
            perror("shmget()");
            return -1;
        }

        /* 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ ν”„λ‘œμ„ΈμŠ€μ˜ λ©”λͺ¨λ¦¬μ— 뢙인닀. */
        shmmem = shmat(shmid, (void *)0, 0666 | IPC_CREAT);
        if(shmmem == (void *)-1) {
            perror("shmat()");
            return -1;
        }

        cVal = (int *)shmmem;
        *cVal = 1;
        for(i = 0; i < 3; i++) {
            *cVal += 1;
            printf("Child(%d) : %d\n", i, *cVal);
            sleep(1);
        }
    } else if(pid > 0) { 		/* λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λ‘œ 곡유 λ©”λͺ¨λ¦¬μ˜ λ‚΄μš©μ„ ν‘œμ‹œ */
        /* 곡유 λ©”λͺ¨λ¦¬ 곡간을 λ§Œλ“ λ‹€. */
        shmid = shmget((key_t)SHM_KEY, sizeof(int), 0666 | IPC_CREAT);
        if(shmid == -1) {
            perror("shmget()");
            return -1;
        }

        /* 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ ν”„λ‘œμ„ΈμŠ€μ˜ λ©”λͺ¨λ¦¬μ— 뢙인닀. */
        shmmem = shmat(shmid, (void *)0, 0);
        if(shmmem == (void *)-1) {
            perror("shmat()");
            return -1;
        }

        cVal = (int *)shmmem;
        for(i = 0; i < 3; i++) {
            sleep(1);
            printf("Parent(%d) : %d\n", i, *cVal);
        }
    }

    shmctl(shmid, IPC_RMID, 0);

    return 0;
}

/*
2개의 ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒμ„±ν•œ ν›„ shmget() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ 곡유 λ©”λͺ¨λ¦¬ λŒ€ν•œ 채널을 κ°€μ Έμ™€μ„œ
shmat() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ 곡유 λ©”λͺ¨λ¦¬λ₯Ό ν˜„μž¬μ˜ ν”„λ‘œμ„ΈμŠ€μ˜ 곡간에 뢙인닀

μžμ‹ ν”„λ‘œμ„ΈμŠ€μ—μ„œλŠ” λ³€μˆ˜μ˜ 값을 μ¦κ°€μ‹œν‚€κ³  이λ₯Ό 화면에 좜λ ₯μ‹œν‚€κ³  1μ΄ˆκ°„ 슬립 λͺ¨λ“œ
λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λŠ” 1μ΄ˆκ°„ 슬립 λͺ¨λ“œμ— λ“€μ–΄κ°„ ν›„ κΉ¨μ–΄λ‚˜μ„œ 곡유 λ©”λͺ¨λ¦¬μ— λŒ€ν•œ λ‚΄μš©μ„ 좜λ ₯ν•œλ‹€
μžμ‹ ν”„λ‘œμ„ΈμŠ€μ—μ„œ 곡유 λ©”λͺ¨λ¦¬λ‘œ 섀정해놓은 λ‚΄μš©μ„ λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€μ—μ„œλ„ 같은 λ©”λͺ¨λ¦¬λ₯Ό κ³΅μœ ν•˜μ—¬ λ™μΌν•œ 값이 좜λ ₯λœλ‹€

@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ gcc -o shm shm.c
@gani0325 ➜ /workspaces/IoT_Linux_RaspberryPi/Process_Signal (main) $ ./shm
*/
gcc -o shm shm.c
./shm

 

728x90
λ°˜μ‘ν˜•
Comments