CS(Computer Science)/UNIX

UNIX - [PIPE - 2]

seongmik 2022. 12. 31. 22:50
반응형

FIFO

  • pipe는 동일 ancestor를 갖는 프로세스들만 연결 가능.
  • fifo는 모든 프로세스들을 연결 가능.
  • UNIX의 file 이름을 부여 받는다.
  • 소유자, 크기, 연관된 접근 허가를 가진다.
  • 일반 file처럼, open, close, read, write, remove가 가능하다.

fifo는 pipe와 다르게 UNIX의 파일 이름을 부여 받는다.

따라서 파일처럼 여러 권한 설정과 파일 크기를 가지고, open, close, read, write, remove 등의 시스템 콜을 사용 가능하다. 

 

사용법

  • fifo 만들기
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
// mode는 보통 0666으로 그냥 줌

→ fifo open (O_RDONLY 또는 O_WRONLY)

→ 여기서 문제! O_RDWR를 쓰는 경우는? (정답은 아래 설명에 포함! ㅎㅎ)

→ fifo에 read 또는 write를 사용해서 사용한다.

 

예시

mkfifo("/tmp/fifo", 0666);
fd = open("/tmp/fifo", O_WRONLY);
// 또는
fd = open("/tmp/fifo", O_WRONLY|O_NONBLOCK);
// O_NONBLOCK은 read/write가 논블락이라는게 아님
// 그냥 오픈 여러개를 동시에 할 때 오픈을 기다리는 프로세스는 blocking되는게 기본인데 이 때 누군가가 오픈 할 때까지 blocking을 하지않고 그냥 오픈을 포기하겠다 (리턴 -1)하겠다는 이야기
  • 일반 open 호출은 다른 프로세스가 읽기 또는 쓰기를 위해 open될 때 까지 blocking한다.
  • Non-blocking open의 경우, 상대 프로세스가 준비되지 않으면, -1 return. 이 때, errno = ENXIO 이다.
int main(void){
		int fd, n;
		char buf[512];

		mkfifo("fifo", 0600);

		fd=open("fifo", O_RDWR);
		
		for (;;){
				n=read(fd, buf, 512);
				write(1, buf, n);
				
				// pipe가 닫힌다면 read의 리턴값이 0임. - 프로세스가 종료했다는 의미
				if (n==0) // O_RDONLY로 열면 read의 return 값이 0일 때 문제가 생김
						printf(".........."); // 만약 O_RDONLY라면 이게 무한반복된다.
		}
}

// --------------------------------

int main(void){
		int fd, j, nread;
		char buf[512];
		
		if ((fd=open("fifo", O_WRONLY|O_NONBLOCK)) < 0){ // O_NONBLOCK을 없애면 
				printf("fifo open failed");
				exit(1);
		}
		
		for (j=0; j<3; j++){
				nread=read(0, buf, 512);
				write(fd, buf, nread);
		}
		
		exit(0);
}

fifo를 통한 통신의 예제이다.  writer 종료 시 blocking 된 채로 기다리기 위해, 그렇지 않다면 무한 0 return

  • reader가 O_RDWR로 fifo를 open한 이유는?
  • O_RDWR로 열어야 하는 상황 → 데이터를 보낸 프로세스가 종료해도 받는 프로세스는 blocking을 유지해야하는 상황에 O_RDWR로 오픈해야한다.
    • 이를 더 자세히 설명하면, fifo의 writer가 모두 사라지면 reader는 더 이상 입력 받기를 기다릴 이유가 없다고 판단해서 block 상태를 해제하고 종료 작업을 수행한다. 하지만 O_RDWR로 fifo를 open한다면 자기 자신이 reader와 writer가 동시에 되기 때문에 다른 모든 writer가 종료해도 reader는 writer가 남아있다고 판단해서 block상태를 유지한다.
  • O_NONBLOCK을 사용하는 이유 : 가끔 open되는 타이밍의 문제로 SIGPIPE SIGNAL을 받고 종료하는 경우가 생길 수 있다.
  • 시간 순서에 따라 아직 OPEN을 안했는데 WRITE하는 경우가 생길 수 있다. (reader가 없는데 read하게됨)
반응형

'CS(Computer Science) > UNIX' 카테고리의 다른 글

UNIX - [Semaphore]  (0) 2023.01.01
UNIX - [시스템 V의 프로세스간 통신 - Message queue]  (0) 2023.01.01
UNIX - [PIPE]  (3) 2022.12.30
UNIX - [MEMORY MAPPING]  (0) 2022.12.30
UNIX - [SIGNAL]  (1) 2022.12.29