LoginSignup
0
0

ノンブロッキングI/Oについて調べてみた

Last updated at Posted at 2024-01-10

はじめに

どうも。こんにちは。
42tokyoといったところで、ソケットプログラミング??を学んでいます。
課題で、ノンブロッキングなファイルディスクリプタを扱うことになり「ノンブロッキングI/O」について調べてみました。
間違い等があれば、ご指摘ください。

結論

「ノンブロッキングI/O」とは、ファイルディスクリプタをノンブロッキングな状態で扱うこと。
ノンブロッキングにすることで、処理効率が上がる場合がある。
「ノンブロッキングI/O」と「非同期I/O」は、異なるもの。

サンプルコード

ノンブロッキングなファイルディスクリプタからread();で読み込んでみる。

non_blocking_read.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int	main(void) {
	// ファイルディスクリプタをノンブロッキングに設定
	int	flags = 0;

	if ((flags = fcntl(STDIN_FILENO, F_GETFL)) == -1) {
		perror("fcntl");
		exit(EXIT_FAILURE);
	}
	flags |= O_NONBLOCK;
	if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1) {
		perror("fcntl");
		exit(EXIT_FAILURE);
	}
	while (1) {
		sleep(3);

		// char	buffer[1024] = {0};
		char	buffer[4] = {0};
		ssize_t	bytes_read = 0;

		errno = 0;

		// ノンブロッキングなファイルディスクリプタからデータを読み取る
		bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));

		if (bytes_read == -1) {
			perror("read");
			if (errno == EAGAIN || errno == EWOULDBLOCK) {
				continue ;
			} else {
				exit(EXIT_FAILURE);
			}
		} else if (bytes_read > 0) {
			// データが読み取られた場合
			printf("Read %zd bytes: %s", bytes_read, buffer);
		} else {
			// データがない場合
			printf("No data available.\n");
			break ;
		}
	}
	return (0);
}

私の理解

  • ノンブロッキングなファイルディスクリプタからの読み取り(read();)では、bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer)); で処理が止まらない。
  • read();の後で、エラー処理を書く必要がある。(戻り値による条件分岐が必要。)
  • errnoがEAGAIN(または、EWOULDBLOCK)のときは、処理は継続。

参考

The Linux Programming Interface
44. 9 Nonblocking I/O (P.915 ~)
44.10 Semantics of read() and write() on Pipes and FIFOs (P.917 ~)

TCP/IP ソケットプログラミング C言語編
5.3 ノンブロッキング I/O (P.82 ~)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0