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

[ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ 닀쀑 처리] ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신 (IPC) with POSIX의 IPC (POSIX λ©”μ‹œμ§€ 큐, λ„€μž„λ“œ μ„Έλ§ˆν¬μ–΄) λ³Έλ¬Έ

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

[ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ 닀쀑 처리] ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신 (IPC) with POSIX의 IPC (POSIX λ©”μ‹œμ§€ 큐, λ„€μž„λ“œ μ„Έλ§ˆν¬μ–΄)

μ§•μ§•μ•ŒνŒŒμΉ΄ 2024. 1. 13. 17:41
728x90
λ°˜μ‘ν˜•

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

 

⭐ POSIX λ©”μ‹œμ§€ ν

μ‹œμŠ€ν…œ V의 λ©”μ‹œμ§€ 큐와 λ§ˆμ°¬κ°€μ§€λ‘œ POSIX λ©”μ‹œμ§€ 큐λ₯Ό μ‚¬μš©ν•˜λ©΄ ν”„λ‘œμ„ΈμŠ€ 간에 λ©”μ‹œμ§€μ˜ ν˜•νƒœλ‘œ 데이터λ₯Ό 전솑할 수 μžˆλ‹€

 

μ‹œμŠ€ν…œ V의 ν•¨μˆ˜λ“€μ΄ μ‹œμŠ€ν…œ 콜인 것에 λΉ„ν•΄μ„œ POSIX ν•¨μˆ˜λŠ” 라이브러리 ν˜•νƒœλ‘œ μ œκ³΅λœλ‹€

POSIX 의 λ©”μ‹œμ§€ νλŠ” mqd_t ν˜•μ„ μ΄μš©ν•œλ‹€

λ©”μ‹œμ§€ 큐의 생성과 νšλ“μ„ μœ„ν•΄ mq_open() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

mq_open() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ mqd_t ν˜•μ„ λ°˜ν™˜λ°›μ€ ν›„ μ΄μš©ν•  수 μžˆλ‹€

λ©”μ‹œμ§€ 큐의 μ†‘μˆ˜μ‹ μ„ μœ„ν•΄ mq_send() 와 mq_receive() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

ν”„λ‘œμ„ΈμŠ€κ°€ 큐의 μ‚¬μš©μ„ 끝낼 λ•Œ mq_close() ν•¨μˆ˜λ‘œ λ‹«λŠ”λ‹€

λ©”μ‹œμ§€ 큐가 더 이상 ν•„μš” μ—†κ²Œ 된 경우 mq_unlink() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ 큐λ₯Ό μ‚­μ œν•œλ‹€

λ©”μ‹œμ§€ 큐의 속성은 mq_getattr() 둜 μ–»λŠ”λ‹€

λ©”μ‹œμ§€ 큐의 속성은 mq_setattr() ν•¨μˆ˜λ‘œ λ³€κ²½ν•œλ‹€

λ©”μ‹œμ§€κ°€ μ˜€λŠ” 것을 λΉ„λ™κΈ°μ μœΌλ‘œ 톡지 λ°›λŠ” mq_notify() ν•¨μˆ˜

// POSIX λ©”μ‹œμ§€ 큐둜 λ©”μ‹œμ§€ 좜λ ₯ν•˜μž Server
#include <stdio.h>
#include <unistd.h>
#include <mqueue.h>

int main(int argc, char **argv)
{
    mqd_t mq;
    struct mq_attr attr;
    const char* name = "/posix_msq"; 		/* λ©”μ‹œμ§€ 큐끼리 κ³΅μœ ν•  이름 */
    char buf[BUFSIZ];
    int n;

    /* λ©”μ‹œμ§€ 큐 μ†μ„±μ˜ μ΄ˆκΈ°ν™” */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = BUFSIZ;
    attr.mq_curmsgs = 0;
    mq = mq_open(name, O_CREAT | O_RDONLY, 0644, &attr);

    /* λ©”μ‹œμ§€ νμ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜¨λ‹€. */
    while(1) {
        n = mq_receive(mq, buf, sizeof(buf), NULL);
    switch (buf[0]) {
        /* λ©”μ‹œμ§€κ°€ ‘q’ 이면 END둜 이동 */
        case 'q':
            goto END;
            break;
        /* λ‹€λ₯Έ λ©”μ‹œμ§€μ΄λ©΄ 화면에 κ°€μ Έμ˜¨ 데이터λ₯Ό 좜λ ₯ν•œλ‹€. */
        default:
            write(1, buf, n);
            break;
        }
    }

END: 			/* λ©”μ‹œμ§€ 큐λ₯Ό 닫은 ν›„ μ •λ¦¬ν•˜κ³  ν”„λ‘œκ·Έλž¨μ„ μ’…λ£Œν•œλ‹€. */
    mq_close(mq);
    mq_unlink(name);

    return 0;
}

/*
μ„œλ²„λ₯Ό μž‘μ„±ν•œλ‹€
μ„œλ²„μ—μ„œ 톡신을 μœ„ν•œ λ©”μ‹œμ§€ 큐λ₯Ό mq_open() ν•¨μˆ˜λ₯Ό 톡해 λ§Œλ“€κ³ ,
mq_receive() ν•¨μˆ˜λ‘œ 데이터λ₯Ό λ°›μ•„μ˜¨λ‹€
κ°€μ Έμ˜¨ 데이터λ₯Ό 화면에 좜λ ₯ν•˜κ³ , "q" κ°€ λ“€μ–΄μ˜¨ κ²½μš°μ— λ©”μ‹œμ§€ 큐λ₯Ό 닫은 ν›„ μ •λ¦¬ν•˜κ³  ν”„λ‘œκ·Έλž¨ μ’…λ£Œ

rt(Realtime) 라이브러리λ₯Ό ν•¨κ»˜ λ§ν¬ν•΄μ•Όν•œλ‹€
gani@gani:~/raspi/Process_Signal $ gcc -o posix_msg_server posix_msg_server.c -lrt
gani@gani:~/raspi/Process_Signal $ ./posix_msg_server &
*/
// POSIX λ©”μ‹œμ§€ 큐둜 λ©”μ‹œμ§€ 좜λ ₯ν•˜μž Client
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <mqueue.h>

int main(int argc, char **argv)
{
    mqd_t mq;
    const char* name = "/posix_msq";
    char buf[BUFSIZ];
    mq = mq_open(name, O_WRONLY);

    /* "Hello, World!"λΌλŠ” λ¬Έμžμ—΄μ„ 보낸닀. */
    strcpy(buf, "Hello, World!\n");
    mq_send(mq, buf, strlen(buf), 0); 	/* λ©”μ‹œμ§€ 큐둜 데이터λ₯Ό 보낸닀. */

    /* "q"둜 μ„€μ •ν•˜κ³  보낸닀. */
    strcpy(buf, "q");
    mq_send(mq, buf, strlen(buf), 0);

    /* λ©”μ‹œμ§€ 큐λ₯Ό λ‹«λŠ”λ‹€. */
    mq_close(mq);

    return 0;
}

/*
λ©”μ‹œμ§€ 큐 ν΄λΌμ΄μ–ΈνŠΈλŠ” λ©”μ‹œμ§€ 큐λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜λŠ” 것이 μ•„λ‹ˆλΌ 기쑴에 μ‘΄μž¬ν•˜κ³  μžˆλŠ” λ©”μ‹œμ§€ 큐λ₯Ό μ—°λ‹€
mq_send() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ”λ°, μ²˜μŒμ—λŠ” λ¬Έμžμ—΄μ„ 보내고 λ‹€μ‹œ "q" λ₯Ό λ³΄λ‚΄μ„œ μ„œλ²„λ₯Ό μ’…λ£Œν•œλ‹€
λ©”μ‹œμ§€ 큐의 μ‚¬μš©μ΄ λλ‚˜λ©΄ mq_close() ν•¨μˆ˜λ‘œ λ©”μ‹œμ§€ 큐λ₯Ό λ‹«μ§€λ§Œ, μ„œλ²„μ™€λŠ” λ‹€λ₯΄κ²Œ λ©”μ‹œμ§€ 큐λ₯Ό μ‚­μ œν•˜μ§€ μ•ŠλŠ”λ‹€

rt(Realtime) 라이브러리λ₯Ό ν•¨κ»˜ λ§ν¬ν•΄μ•Όν•œλ‹€
gani@gani:~/raspi/Process_Signal $ gcc -o posix_msg_client posix_msg_client.c -lrt
gani@gani:~/raspi/Process_Signal $ ./posix_msg_client 
*/
gcc -o posix_msg_server posix_msg_server.c -lrt
./posix_msg_server &

gcc -o posix_msg_client posix_msg_client.c -lrt
./posix_msg_client

 

β˜‘οΈ λ„€μž„λ“œ μ„Έλ§ˆν¬μ–΄

λ¦¬λˆ…μŠ€μ—μ„œ μ„Έλ§ˆν¬μ–΄λ₯Ό 보닀 μ‰½κ²Œ μ‚¬μš©ν•  수 μžˆλŠ” 라이브러리 ν˜•νƒœμ˜ ν•¨μˆ˜λ“€

μ„Έλ§ˆν¬μ–΄λ₯Ό μ‚¬μš©ν•˜κΈ° 전에 λ°˜λ“œμ‹œ sem_t ν˜•μ„ μ΄ˆκΈ°ν™” ν•΄μ•Ό ν•œλ‹€

μ΄ˆκΈ°ν™”λŠ” sem_open() ν•¨μˆ˜λ₯Ό μ‚¬μš©

sem_open() ν•¨μˆ˜μ˜ 첫 번째 인자둜 λ‹€λ₯Έ μ„Έλ§ˆν¬μ–΄μ™€ ꡬ뢄할 수 μžˆλŠ” 이름 λ“€μ–΄κ°€λ―€λ‘œ λ„€μž„λ“œ(named) μ„Έλ§ˆν¬μ–΄λΌκ³  λΆ€λ₯Έλ‹€

μ΄ˆκΈ°ν™”κ°€ λλ‚˜λ©΄ P μ—°μ‚°κ³Ό V 연산을 μˆ˜ν–‰ν•˜λ©΄ λ˜λŠ”λ°, sem_post() 와 sem_wait() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

μ‚¬μš©μ΄ λ‹€ λλ‚œ μ„Έλ§ˆν¬μ–΄λŠ” sem_close() ν•¨μˆ˜λ‘œ λ‹«κ³ , μ œκ±°λŠ” sem_destroy() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€

μ‚¬μš©μ΄ λ‹€ λλ‚œ ν›„ 더 이상 ν•„μš”κ°€ μ—†μ–΄μ‘Œμ„ λ•Œ sem_unlink() μ΄μš©ν•΄μ„œ λ„€μž„λ“œ μ„Έλ§ˆν¬μ–΄λ₯Ό μ‚­μ œν•œλ‹€

phread 라이브러리λ₯Ό λ§ν¬ν•˜μ—¬ μ†ŒμŠ€ μ½”λ“œλ₯Ό λΉŒλ“œν•΄μ•Ό ν•œλ‹€

// 라이브러리둜 μ„Έλ§ˆν¬μ–΄ μ‚¬μš©ν•˜κΈ°
#include <stdio.h> 		/* printf() ν•¨μˆ˜λ₯Ό μœ„ν•œ 헀더 파일 */
#include <fcntl.h> 		/* O_CREAT, O_EXEC 맀크둜λ₯Ό μœ„ν•œ 헀더 파일 */
#include <unistd.h>
#include <semaphore.h> 		/* sem_open(), sem_destroy(), sem_wait() λ“± ν•¨μˆ˜λ₯Ό μœ„ν•œ 헀더 파일 */

sem_t *sem; 			/* μ„Έλ§ˆν¬μ–΄λ₯Ό μœ„ν•œ μ „μ—­ λ³€μˆ˜ */
static int cnt = 0; 		/* μ„Έλ§ˆν¬μ–΄μ—μ„œ μ‚¬μš©ν•  μž„κ³„ ꡬ역 λ³€μˆ˜ */

void p() 			/* μ„Έλ§ˆν¬μ–΄μ˜ P μ—°μ‚° */
{
    cnt--;
    sem_post(sem);
}

void v() 			/* μ„Έλ§ˆν¬μ–΄μ˜ V μ—°μ‚° */
{
    cnt++;
    sem_wait(sem);
}

int main(int argc, char **argv)
{
    const char* name = "posix_sem";
    unsigned int value = 8; 	/* μ„Έλ§ˆν¬μ–΄μ˜ κ°’ */

    /* μ„Έλ§ˆν¬μ–΄ μ—΄κΈ° */
    sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR, value);
    while(1) {
        if(cnt >= 8) {
            p();
            printf("decrease : %d\n", cnt);
            break;
        } else {
            v();
            printf("increase : %d\n", cnt) ;
            usleep(100);
        }
    }

    /* λ‹€ μ“΄ μ„Έλ§ˆν¬μ–΄ λ‹«κ³  정리 */
    sem_close(sem);
    printf("sem_destroy return value : %d\n", sem_destroy(sem));

    /* μ„Έλ§ˆν¬μ–΄ μ‚­μ œ */
    sem_unlink(name);

    return 0;
}

/*
phread 라이브러리λ₯Ό λ§ν¬ν•œλ‹€
μ‹œμŠ€ν…œ V의 μ„Έλ§ˆν¬μ–΄μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€

gani@gani:~/raspi/Process_Signal $ gcc -o posix_sem posix_sem.c -pthread
gani@gani:~/raspi/Process_Signal $ ./posix_sem 
*/
gcc -o posix_sem posix_sem.c -pthread
./posix_sem

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