파일 블로킹/논블로킹

Juni and ING·2020년 8월 26일
0

설명

Blocking

어떠한 자원에 접근했을 때, 현재 접근은 불가하지만 반드시 획득해야 할 때 가능해질 때까지 Holding되는 것

Non-blocking

어떠한 자원에 접근했을 때, 현재 접근이 불가하지만 굳히 당장 획득할 필요가 없을 때 Holding을 하지 않고 다음을 진행하는 것


설정 방법

  1. open() 실행 시, O_NONBLOCK 플래그 지정/미지정
  2. open() 이후, fcntl() 함수를 사용하여 O_NONBLOCK를 설정/해제

함수

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */);

인자

fd

파일 디스크립터

cmd

파일 제어 커맨드

  • F_GETFL : File open flags를 얻어옴
  • F_SETFL : File open flags를 재설정
  • 그 외 커맨드는 man 페이지 참조

...

제어 커맨드에 따라 필요한 가변 인자

반환값

성공 시

커맨드에 따른 반환값

실패 시

-1


Example

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include <errno.h>

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


static void dump_stdin(void)
{
	char buf[128];
	int fd = STDIN_FILENO,
		cnt, flags,
		MAX_BUF_IDX = (sizeof(buf) / sizeof(char)) - 1;

	printf("Trying to read...\n");
	cnt = read(fd, buf, MAX_BUF_IDX);
	if(cnt >= 0){
		buf[cnt] = 0;
		printf("Read : %s\n", buf);
	}
	else {
		fprintf(stderr, "read() FAIL : %s\n", strerror(errno));
	}


	flags = fcntl(fd, F_GETFL);
	if(flags < 0){
		fprintf(stderr, "fcntl(F_GETFL) FAIL : %s\n", strerror(errno));
		goto EXCEPTION;
	}

	if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){
		fprintf(stderr, "fcntl(F_SETFL) FAIL : %s\n", strerror(errno));
		goto EXCEPTION;
	}

	printf("Trying to read...\n");
	cnt = read(fd, buf, MAX_BUF_IDX);
	if(cnt >= 0){
		buf[cnt] = 0;
		printf("Read : %s\n", buf);
	}
	else {
		fprintf(stderr, "read() again FAIL : %s\n", strerror(errno));
	}

	if(fcntl(fd, F_SETFL, flags) < 0){
		fprintf(stderr, "<<WARNING>> fcntl(F_SETFL) again FAIL : %s\n", strerror(errno));
	}

	return;

EXCEPTION:
	return;
}

int main(int argc, char **argv)
{
	dump_stdin();

	return 0;
}

profile
인기는 없지만 그래도 임베디드를 사랑하는 한 개발자

0개의 댓글