2012. 7. 13. 16:33

a.out 프로세스에서 공유메모리를 생성하여 공유메모리에 쓰면 b.out 프로세스에서 공유 메모리에 저장된

데이터를 읽어서 출력한다.


a.out
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#define SIZE 1024

void signalHandler(int signo);
int shmid;

main()
{
    void *shmaddr;

    /* 1234 키의 공유메모리 생성 */
    if((shmid=shmget((key_t)1234, SIZE, IPC_CREAT|0666)) == -1) {
       perror("shmid failed");
       exit(1);
    }

    /* shmid 공유메모리를 호출 프로세스 메모리 영역으로 첨부 */
    if((shmaddr=shmat(shmid, (void *)0, 0)) == (void *)-1) {
       perror("shmat failed");
       exit(1);
    }

    /* 공유메모리에 데이터 쓰기 */
    strcpy((char *)shmaddr, "Linux Programming");

    /* 공유메모리를 호출 프로세스의 메모리 영역에서 분리 */
    if(shmdt(shmaddr) == -1) {
       perror("shmdt failed");
       exit(1);
    }

    /* SIGINT 시그널 받으면 signalHandler 실행하도록 설정 */
    signal(SIGINT, signalHandler);
    pause();
}

void signalHandler(int signo)
{
    /* shmid 공유메모리 삭제 */
    if(shmctl(shmid, IPC_RMID, 0) == -1) {
       perror("shmctl failed");
       exit(1);
    }
    exit(0);
}


b.out
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#define SIZE 1024

main()
{
    int shmid;
    void *shmaddr;
    struct shmid_ds shm_stat;

    /* 1234 키의 공유메모리 있으면 접근해서 식별자 얻음 */
    if((shmid=shmget((key_t)1234, SIZE, IPC_CREAT|0666)) == -1) {
       perror("shmid failed");
       exit(1);
    }

    /* shmid 공유메모리를 호출 프로세스 메모리 영역으로 첨부 */
    if((shmaddr=shmat(shmid, (void *)0, 0)) == (void *)-1) {
       perror("shmat failed");
       exit(1);
    }

    /* 공유메모리에 저장된 데이터 출력 */
    printf("data read from shared memory : %s\n", (char *)shmaddr);

    /* shmid 공유메모리 정보를 얻어 shm_stat에 저장 */
    if(shmctl(shmid, IPC_STAT, &shm_stat) == -1) {
       perror("shmctl failed");
       exit(1);
    }

    /* 공유메모리를 호출 프로세스의 메모리 영역에서 분리 */
    if(shmdt(shmaddr) == -1) {
       perror("shmdt failed");
       exit(1);
    }

    /* shm_stat.shm_cpid 프로세스에게 SIGINT 시그널 보냄 */
    kill(shm_stat.shm_cpid, SIGINT);

    exit(0);
}

[localhost@local]# a.out &
[localhost@local]# b.out
data read from shared memory : Linux Programing
[1]+ Done                 a.out


--------------------------------------------------------------------------------------------------------
공유 메모리를 이용해 여러 프로세스에게 보내는 데이터 받기

a.out프로세스와 b.out 프로세스는 하나 이상의 프로세스인 b,c ... 에서 데이터를 공유 메모리에 저장하면

프로세스 a는 공유 메모리에서 데이터를 읽어 출력하는 프로그램이다.

프로세스 b,c ... 는 quit를 입력받을 때 까지 반복 실행하고 프로세스 a는 읽은 데이터가 quit 공유 메모리

를 이용하고 있는 프로세스가 자신 외에 없을 때 종료한다.


a.out

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SIZE 1024

main()
{
    struct check_data {
       int check;
       char data[SIZE];
    } *shared_data;
    int shmid;
    void *shmaddr;
    struct shmid_ds shm_stat;

    /* 1234 키의 공유메모리 생성 */
    if((shmid=shmget((key_t)1234, sizeof(struct check_data), IPC_CREAT|0666)) == -1) {
       perror("shmid failed");
       exit(1);
    }

    /* shmid 공유메모리를 호출 프로세스 메모리 영역으로 첨부 */
    if((shmaddr=shmat(shmid, (void *)0, 0)) == (void *)-1) {
       perror("shmat failed");
       exit(1);
    }

    shared_data = (struct check_data *)shmaddr;
    /* check가 0이면 공유메모리에 도착한 데이터가 없다는 의미 */
    shared_data->check = 0;

    while(1) {
       /* 공유메모리에 데이터 도착하면 */
       if(shared_data->check) {
          printf("data read from shared memory : %s", shared_data->data);
          sleep(1);
          shared_data->check = 0;
          /* 읽은 데이터가 ‘quit’이면 */
          if(!strncmp(shared_data->data, "quit", 4)) {
             /* shmid 공유메모리 정보를 얻어 shm_stat에 저장 */
             if(shmctl(shmid, IPC_STAT, &shm_stat) == -1) {
                perror("shmctl failed");
                exit(1);
             }
             /* 공유메모리를 이용하는 프로세스가 나 혼자면 while 문 벗어남 */
             if(shm_stat.shm_nattch == 1)
                break;
          }
       }
       sleep(1);
    }

    /* 공유메모리를 호출 프로세스의 메모리 영역에서 분리 */
    if(shmdt(shmaddr) == -1) {
       perror("shmdt failed");
       exit(1);
    }

    /* shmid 공유메모리 삭제 */
    if(shmctl(shmid, IPC_RMID, 0) == -1) {
       perror("shmctl failed");
       exit(1);
    }
    exit(0);
}


b.out

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SIZE 1024

main()
{
    struct check_data {
       int check;
       char data[SIZE];
    } *shared_data;
    int shmid;
    void *shmaddr;
    char buffer[SIZE];

    /* 1234 키의 공유메모리 있으면 접근해서 식별자 얻음 */
    if((shmid=shmget((key_t)1234, SIZE, IPC_CREAT|0666)) == -1) {
       perror("shmid failed");
       exit(1);
    }

    /* shmid 공유메모리를 호출 프로세스 메모리 영역으로 첨부 */
    if((shmaddr=shmat(shmid, (void *)0, 0)) == (void *)-1) {
       perror("shmat failed");
       exit(1);
    }

    shared_data = (struct check_data *)shmaddr;

    while(1) {
       /* 공유메모리의 check가 1이면 기다림 */
       while(shared_data->check) {
          sleep(1);
          printf("waiting...\n");
       }
       printf("input data ==> ");
       fgets(buffer, SIZE, stdin);

       /* 공유메모리에 데이터 쓰기 */
       strncpy(shared_data->data, buffer, SIZE);
       shared_data->check = 1;
       /* 쓴 데이터가 ‘quit’이면 while 문 벗어남 */
       if(!strncmp(shared_data->data, "quit", 4)) {
          break;
       }
    }
    /* 공유메모리를 호출 프로세스의 메모리 영역에서 분리 */
    if(shmdt(shmaddr) == -1) {
       perror("shmdt failed");
       exit(1);
    }
    exit(0);
}

터미널 A
[localhost@local]#a.out &
[localhost@local]#b.out
input data ==> data read from shared memory : aaa
bbb
data read from shared memory : bbb
waiting....
waiting....
input data ==> data read from shared memory : ccc
ddd
data read from shared memory : ddd
waiting....
waiting....
input data ==> quit
[localhost@local]# data read from shared memory : quit
data read from shared memory : quit

[1]+ Done  a.out

터미널 B
[localhost@local]#b.out
input data ===> aaa
waiting....
waiting....
input data ===> ccc
waiting
waiting....
input data ===> quit

Posted by 몰라욧