<<戻る

2004年10月07日

ファイルディスクリプタの状態を調査するプログラム

 

/******************************************************************************/
/*
 * $Id$
 *
 * 概要
 * ファイルディスクリプタの状態を調査するプログラム。
 * t_pt4loopスレッドがダミーデータを生成し続ける時、t_pt4fileスレッドがファイル
 * 複製、別名、削除、圧縮を実行した時どのような状態になるのか実験する。
 * このプログラムによりディスクリプタの概念の詳細を理解する。
 *
 * $Author$
 * $Date$
 * $Rev$
 *
 * Copyright(C) 2004 Satoshi Okita All Rights Reserved.
 */
/******************************************************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEST_FILE                       "data.dat"
#define RENAME_FILE                     "data_rename.dat"

void *loop_thread(void *val)
{
        FILE *fp = NULL;
        int cnt = 0;
        char buf[1024];

        fp = fopen(DEST_FILE, "a");
        if ( fp == NULL )
        {
                perror("fopen error in loop_thread.\n");
                return NULL;
        }

        while ( cnt < 10 )
        {
                memset(buf, 0, sizeof(buf));
                snprintf(buf, sizeof(buf), "%d", cnt);
                printf("%d\n", cnt++);
                fwrite(buf, 1, strlen(buf), fp);

                sleep(1); /* weight */
                fflush(fp);
        }

        fclose(fp);

        /* TODO とりあえずNULL */
        return NULL;
}

void *rename_file_thread(void *val)
{
        sleep(2); /* 0.0003s */

        /* 別名テスト */
        if ( rename(DEST_FILE, RENAME_FILE) != 0 )
        {
                perror("error");
                return NULL;
        }
        else
        {
                printf("rename successfully.\n");
        }

        /* TODO とりあえずNULL */
        return NULL;
}

/* 複製テスト */
void *copy_file_thread(void *val)
{
        /* TODO とりあえずNULL */
        return NULL;

}

/* 削除テスト */
void *delete_file_thread(void *val)
{
        sleep(2); /* 0.0003s */
        if ( unlink(DEST_FILE) != 0 )
        {
                perror("unlink error\n");
        }
        else
        {
                printf("unlink successfully\n");
        }
        /* TODO とりあえずNULL */
        return NULL;
}

/* 圧縮テスト */
void *compress_file_thread(void *val)
{
        printf("圧縮テスト開始\n");
        FILE *fp = NULL;
        gzFile gfp;
        int rc;
        int c; /* データ格納 */

        /* ファイルオープン */
        fp = fopen(DEST_FILE, "r");
        if ( fp == NULL )
        {
                perror("fopen error in compress_file_thread\n");
        }
        gfp = gzopen(DEST_FILE ".gz", "wb");
        if (gfp == NULL )
        {
                perror("gzopen error\n");
        }

        while ( (c = fgetc(fp)) != EOF )
        {
                gzputc(gfp, c);
        }

        /* ファイルクローズ */
        fclose(fp);
        rc = gzclose(gfp);
        if ( rc != Z_OK )
        {
                perror(gzerror(gfp, &rc));
        }
        printf("圧縮テスト終了\n");

        /* TODO とりあえずNULL */
        return NULL;
}

/* 重複テスト */
void *repeat_file_thread(void *val)
{
        FILE *fp = NULL;
        int cnt = 0;
        char buf[1024];

        fp = fopen(DEST_FILE, "a");
        if ( fp == NULL )
        {
                perror("fopen error in repeat_file_thread.\n");
                return NULL;
        }

        while ( cnt < 10 )
        {
                memset(buf, 0, sizeof(buf));
                snprintf(buf, sizeof(buf), "%d", cnt);
                printf("%d\n", cnt++);
                fwrite(buf, 1, strlen(buf), fp);
                fflush(fp);

                sleep(1); /* weight */
        }

        fclose(fp);

        /* TODO とりあえずNULL */
        return NULL;
}

void usage()
{
        printf("usage: command (1|2|3|4|)\n");
        printf("1:別名テスト\n");
        printf("2:複製テスト\n");
        printf("3:削除テスト\n");
        printf("4:圧縮テスト\n");
        printf("5:重複テスト\n");

}


int main(int argc, char *argv[])
{
        pthread_t       t_pt4loop;
        pthread_t       t_pt4rename;
        pthread_t       t_pt4copy;
        pthread_t       t_pt4delete;
        pthread_t       t_pt4compress;
        pthread_t       t_pt4repeat;
        void       *ret_pt4loop;
        void       *ret_pt4rename;
        void       *ret_pt4copy;
        void       *ret_pt4delete;
        void       *ret_pt4compress;
        void       *ret_pt4repeat;
        int                 command_arg;

        switch ( argc )
        {
                case 2:
                        if ( strlen(argv[1]) == 1 )
                        {
                                command_arg = atoi(argv[1]);
                        }
                        break;
                default:
                        usage();
                        return 0;
        }

        /* スレッドの起動 */
        pthread_create(&t_pt4loop, NULL, loop_thread, "loop");

        switch ( command_arg )
        {
                case 1:
                        printf("exec 1\n");
                        pthread_create(&t_pt4rename, NULL, rename_file_thread, "loop");
                        break;
                case 2:
                        pthread_create(&t_pt4copy, NULL, copy_file_thread, "loop");
                        break;
                case 3:
                        printf("exec 3\n");
                        pthread_create(&t_pt4delete, NULL, delete_file_thread, "loop");
                        break;
                case 4:
                        pthread_create(&t_pt4compress, NULL, compress_file_thread, "loop");
                        break;
                case 5:
                        pthread_create(&t_pt4repeat, NULL, repeat_file_thread, "loop");
                        break;
                default:
                        perror("command error\n");
                        break;
        }

        /* main関数のスレッドはt_pt4loopが終了するまで待機 */
        pthread_join(t_pt4loop, &ret_pt4loop);
        return 0;
}