카테고리 없음

IPC :: pipe 함수, mkfifo 함수, 공유 메모리

newind2000 2015. 7. 30. 17:39

==================================Outline====================================

IPC

- pipe 함수

- mkfifo 함수

- 공유 메모리

----------------------------------------------------------------------------

 

pipe 함수

 

파이프 함수를 사용하면 변수를 통하여 서로 데이터를 주고 받을 수 있다. 하지만 이 같은 경우는 복사된 동일한 프로세스만이 변수를 사용한 데이터의 공유가 가능할 뿐이다.

 

 

#include <unistd.h>

 

int pipe(int filedes[2]);

 

 

 

mkfifo 함수

 

서로 상이한 프로그램 간의 데이터 입출력을 위해서는 파일을 사용하여야 한다. 이 때 사용하는 함수가 'mkfifo'이다.

 

#include <sys/types.h>

#include <sys/stat.h>

 

int mkfifo(const char *pathname, mode_t mode);

 

 

mkfifomode에 대해서 알아보자.

 

File mode bits:

 

S_IRWXU

read, write, execute/search by owner

 

S_IRUSR

read permission, owner

 

S_IWUSR

write permission, owner

 

S_IXUSR

execute/search permission, owner

 

S_IRWXG

read, write, execute/search by group

 

S_IRGRP

read permission, group

 

S_IWGRP

write permission, group

 

 

S_IXGRP

execute/search permission, group

 

S_IRWXO

read, write, execute/search by others

 

S_IROTH

read permission, others

 

S_IWOTH

write permission, others

 

S_IXOTH

execute/search permission, others

 

S_ISUID

set-user-ID on execution

 

S_ISGID

set-group-ID on execution

 

S_ISVTX

on directories, restricted deletion flag

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main()
{
  if(mkfifo("/tmp/myfifo_r", S_IRUSR|S_IWUSR) == -1)
  {
    return 1;
  }
  printf("Sucess Named PIPE : tmp/myfifo_r\n");

  return 0;
}

 

//리눅스는 확장자로 파일을 구분하지 않는다.

//fifo(first in, first out)

 

 

 

서버와 클라이언트가 통신하는 IPC를 만들어보자.

 

다수의 클라이언트가 접속하는 경우 파이프는 부적합하다. 접속자의 수만큼 파이프를 만들어야 하기 때문이다.

/// pipe_client.c ///

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define MAXLINE 1024

int main(void)
{
  int rfd, wfd;    //file descriptors
  char buf[MAXLINE];  //buf
  
  if(  (rfd = open("/tmp/myfifo_w", O_RDWR) ) < 0)  //write pipe open
  {                          //if error, terminate program
    perror("read open error");
    return 0;
  }

  if(  (wfd = open("/tmp/myfifo_r", O_RDWR) ) < 0)  //read pipe open
  {                          //if error, terminate program
    perror("write open error");
    return 0;
  }
  
  while(1)
  {
    printf("> ");
    fflush(stdout);          //empty print buff
    memset(buf, 0x00, MAXLINE);    //empty buff
    if(  read(0, buf, MAXLINE)  < 0  )  //if none read from keyboard, terminate program
    {
      printf("error\n");
      return 1;
    }
    if(  strncmp(buf, "quit\n"5== 0  )  //if input "quit" terminate program
      break;

    write( wfd, buf, strlen(buf) );      //write at write pipe
    read( rfd, buf, MAXLINE );        //read from read pipe
    printf("Server -> %s", buf);      //print what read from server
  }

  close(wfd);          //close write pipe
  close(rfd);          //close read pipe
  return 0;
}

/// pipe_server.c ///


#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define MAXLINE 1024

int main(void)
{
  int rfd, wfd;    //file descriptors
  char buf[MAXLINE];  //buf
  
  mkfifo("/tmp/myfifo_r", S_IRUSR|S_IWUSR);    //write pipe open
  mkfifo("/tmp/myfifo_w", S_IRUSR|S_IWUSR);    //read pipe open
  if(  (rfd = open("/tmp/myfifo_r", O_RDWR) ) == -1)  //if error at opening read pipe, terminate program 
  {
    perror("rfd error");
    return 0;
  }

  if(  (wfd = open("/tmp/myfifo_w", O_RDWR) ) == -1)  //if error at opening write pipe, terminate program
  {
    perror("wfd error");
    return 0;
  }
  
  while(1)
  {
    memset(buf, 0x00, MAXLINE);          //empty R/W buff 
    if(  read(rfd, buf, MAXLINE)  < 0)      //if error at reading from pipe, terminate program
    {
      perror("Read Error::");
      return 1;
    }
    printf("read : %s", buf);          //print buff read from read pipe
    lseek(wfd, 0, SEEK_SET);          //cursor at beginning of buff
    write(wfd, buf, MAXLINE);          //echo what read from buff
  }
  return 0;
  
}




 

 

파이프는 큰 데이터를 소수의 클라이언트가 사용할 때 쓰고, 도메인은 적은 데이터를 다수의 클라이언트가 사용할 때 쓴다.

 

공유 메모리

 

shmget함수를 사용한다.

 

#include <sys/types.h>

#include <sys/shm.h>

 

int shmget(key_t key, int size, int shmflg);

#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int shmid;

  int *cal_num;
  void *shared_memory = NULL;

  shmid = shmget( (key_t)1234sizeof(int), 0);
  if (shmid == -1)
  {
    perror("shmget failed : ");
    exit(0);
  }
  shared_memory = shmat(shmid, NULL, 0);
  if (shared_memory == (void *)-1)
  {
    perror("shmat failed : ");
    exit(0);
  }

  cal_num = (int *)shared_memory;
  while(1)
  {
    sleep(1);
    printf("read data : %d\n", *cal_num);
  }
  return 1;
}


#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int shmid;

  int *cal_num;
  void *shared_memory = NULL;

  shmid = shmget( (key_t)1234sizeof(int), 0666|IPC_CREAT);
  if (shmid == -1)
  {
    perror("shmget failed : ");
    exit(0);
  }
  shared_memory = shmat(shmid, NULL, 0);
  if (shared_memory == (void *)-1)
  {
    perror("shmat failed : ");
    exit(0);
  }

  cal_num = (int *)shared_memory;
  while(1)
  {
    *cal_num = *cal_num +2;
    sleep(1);
  }
  return 1;
}

 



소스 파일들



myfifo.c


pipe.c


pipe_client.c


pipe_server.c


shm_consumer.c


shm_producer.c




 

반응형