SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ファイルディスクリプタについて

ファイルディスクリプタについて(2)
~イベント用ファイルディスクリプタ「eventfd」の特徴

第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

類似の機能について

 類似した機能として、socketpair(2)および名前なしpipeがありますが、これらはディスクリプタと似て異なる点もあります。同じ動きをするプログラムは、それぞれ下記のとおりとなります。

 なお、こちらがpipe(2)リファレンスsocketpair(2)リファレンスになります。

pipe_sample.c
#include <sys/wait.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

int main( int argc, char ** argv ) {
    int   fd[2], j;
    uint64_t u;

    if( argc < 3 ) {
	fprintf( stderr, "Usage: %s <num> <num>...\n", argv[0] );
	exit( EXIT_FAILURE );
    }

    pipe( fd );
    switch( fork( )) {
    case 0:
	close( fd[0] );
	for( j = 2; j < argc; j ++ ) {
	    u = strtoull( argv[j], NULL, 0 );
	    write( fd[1], &u, sizeof( u ));
	}
	close( fd[1] );
	printf( "Child completed\n" );
	exit( EXIT_SUCCESS );

    default:
	close( fd[1] );
	printf( "Parent sleep %d sec.\n", atoi( argv[1] ));
	sleep( atoi( argv[1] ));

	while( read( fd[0], &u, sizeof( uint64_t )) > 0 )
	    printf( "parent_read by pipe:[%lld]\n", ( unsigned long long )u );

	close( fd[0] );
	printf( "Parent completed\n" );
	exit( EXIT_SUCCESS );
    }
}
socketpair_sample.c
#include <sys/wait.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>

int main( int argc, char ** argv ) {
    int   fd[2], j;
    uint64_t u;

    if( argc < 3 ) {
	fprintf( stderr, "Usage: %s <num> <num>...\n", argv[0] );
	exit( EXIT_FAILURE );
    }

    socketpair( AF_LOCAL, SOCK_STREAM, 0, fd );
    switch( fork( )) {
    case 0:
	close( fd[0] );
	for( j = 2; j < argc; j ++ ) {
	    u = strtoull( argv[j], NULL, 0 );
	    write( fd[1], &u, sizeof( u ));
	}
	close( fd[1] );
	printf( "Child completed\n" );
	exit( EXIT_SUCCESS );

    default:
	close( fd[1] );
	printf( "Parent sleep %d sec.\n", atoi( argv[1] ));
	sleep( atoi( argv[1] ));

	while( read( fd[0], &u, sizeof( uint64_t )) > 0 )
	    printf( "parent_read by sock:[%lld]\n", ( unsigned long long )u );

	close( fd[0] );
	printf( "Parent completed\n" );
	exit( EXIT_SUCCESS );
    }
}

 それぞれの実行結果は下記の通りです。

# ./eventfd_sample 2 1 2 3 4 5
Child completed
Parent sleep 2 sec.
Parent read by eventfd:[15]   ← 1~5 の合計値になる(必ずではない)
# ./pipe_sample 2 1 2 3 4 5
Child completed
Parent sleep 2 sec.
parent_read by pipe:[1]       ← 個別で読み込まれる
parent_read by pipe:[2]
parent_read by pipe:[3]
parent_read by pipe:[4]
parent_read by pipe:[5]
Parent completed
# ./socketpair_sample 2 1 2 3 4 5
Child completed
Parent sleep 2 sec.
parent_read by sock:[1]     ← 個別で読み込まれる
parent_read by sock:[2]
parent_read by sock:[3]
parent_read by sock:[4]
parent_read by sock:[5]
Parent completed
# 

次のページ
特徴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ファイルディスクリプタについて連載記事一覧

もっと読む

この記事の著者

赤松 エイト(エイト)

(株)DTSに勤てます。WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。mixiもやってまして、こちらは子育てとか日々の日記メインです。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4837 2010/02/05 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング