天天看點

非阻塞檔案I/O

1.以非阻塞方式打開檔案

調用open時,使用O_NONBLOCK選項即可。

執行個體:

//noblock.c

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <errno.h>

#define MAX 100000

#define LEN 1024 

int main(int argc, char *argv[ ])

{

    int fd1, fd2;

    FILE *fp;

    char buf[MAX];

    int n, rest;

    char *p = buf;

    char content[LEN];

    if(argc != 3){

        printf("expect args/n");

        exit(1);

    }

    fd1 = open(argv[1], O_RDONLY);

    if(fd1 == -1){

        perror("fail to read");

        exit(1);

    }

    fp = fopen(argv[2], "w");

    if(fp == NULL){

        perror("fail to read");

        exit(1);

    }

    fd2 = open("test.txt", O_WRONLY);

    if(fd2 == -1){

        perror("fail to read");

        exit(1);

    }

    rest = read(fd1, buf, MAX);

    printf("get %d bytes from %s/n", rest, argv[1]);

    while(rest > 0){

        errno = 0;

        n = write(fd2, p, rest);

        fprintf(fp, "write %d, errno %s/n", n, strerror(errno));

        if(rest > 0){

            p += n;

            rest -= n;

        }

    }

    printf("done/n");

    return 0;

}

觀察輸出系統中調用出錯原因的檔案,可以看到很多錯誤号為EAGAIN的出錯提示資訊。

2.将一個打開的檔案設定為非阻塞方式

用fcntl,先用F_GETFL得到狀态标志字,之後用F_SETFL設定相應的位。

//noblock_fcntl.c

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <errno.h>

#define MAX 100000

#define LEN 1024

int main(int argc, char *argv[ ])

{

    int fd1, fd2;

    FILE *fp;

    char buf[MAX];

    int n, rest;

    char *p = buf;

    char content[LEN];

    int flags;

    if(argc != 3){

        printf("expect args/n");

        exit(1);

    }

    fd1 = open(argv[1], O_RDONLY);

    if(fd1 == -1){

        perror("fail to read");

        exit(1);

    }

    fd2 = open(argv[2], O_WRONLY);

    if(fd2 == -1){

        perror("fail to read");

        exit(1);

    }

    fp = fdopen(fd2, "w");

    if(fp == NULL){

        perror("fail to open");

        exit(1);

    }

    flags = fcntl(STDOUT_FILENO, F_GETFL, 0);

    if(flags == -1){

        perror("fail to fcntl");

        exit(1);

    }

    flags |= O_NONBLOCK;

    if(fcntl(STDOUT_FILENO, F_SETFL, flags) == -1){

        perror("fail to fcntl");

        exit(1);

    }

    rest = read(fd1, buf, MAX);

    printf("get %d bytes from %s/n", rest, argv[1]);

    while(rest > 0){

        errno = 0;

        n = write(STDOUT_FILENO, p, rest);

        fprintf(fp, "write %d, errno %s/n", n, strerror(errno));

        if(rest > 0){

            p += n;

            rest -= n;

        }

    }

    printf("done/n");

    close(fd1);

    fclose(fp);

    return 0;

}