UNIX编程(14)-高级IO

1.非阻塞IO

对于一个给定的描述符有两种方法对其指定非阻塞IO

1)如果调用open获得描述符,则可指定O_NONBLOCK标志

2)对于一个已经打开的描述符,则可调用fcntl由该函数打开O_NONBLOCK文件状态标志

#include "apue.h"
#include <errno.h>
#include <fcntl.h>

char    buf[500000];

int
main(void)
{
    int     ntowrite, nwrite;
    char    *ptr;

    ntowrite = read(STDIN_FILENO, buf, sizeof(buf));
    fprintf(stderr, "read %d bytes\n", ntowrite);

    set_fl(STDOUT_FILENO, O_NONBLOCK); /* set nonblocking */

    ptr = buf;
    while (ntowrite > 0) {
        errno = 0;
        nwrite = write(STDOUT_FILENO, ptr, ntowrite);
        fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno);

        if (nwrite > 0) {
            ptr += nwrite;
            ntowrite -= nwrite;
        }
    }

    clr_fl(STDOUT_FILENO, O_NONBLOCK); /* clear nonblocking */

    exit(0);
}

2. 记录锁

记录锁锁定文件中的一个区域

#include <fcntl.h>

int fcntl(int filedes, int cmd, ... /* struct
 flock *flockptr */ );

扫描二维码关注公众号,回复: 1348627 查看本文章

Returns: depends on cmd if OK (see following), 1 on error

cmd is F_GETLK, F_SETLK, or F_SETLKW

struct flock {
     short l_type;   /* F_RDLCK, F_WRLCK, or F_UNLCK */
     off_t l_start;  /* offset in bytes, relative to l_whence */
     short l_whence; /* SEEK_SET, SEEK_CUR, or SEEK_END */
     off_t l_len;    /* length, in bytes; 0 means lock to EOF */
     pid_t l_pid;    /* returned with F_GETLK */
   };

例:加锁和解锁一个文件区域的函数

#include "apue.h"
#include <fcntl.h>

int
lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
    struct flock lock;

    lock.l_type = type;     /* F_RDLCK, F_WRLCK, F_UNLCK */
    lock.l_start = offset;  /* byte offset, relative to l_whence */
    lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
    lock.l_len = len;       /* #bytes (0 means to EOF) */

    return(fcntl(fd, cmd, &lock));
}

锁的隐含继承和释放

1)

2)

3)

4)

建议性锁和强制性锁

3.STREAMS

1)putmsg和putpmsg函数

2)ioctl

3)写至流

4)写模式

5)getmsg和getpmsg函数

6)读模式

 4.IO多路转接

#include <sys/select.h>

int select(int maxfdp1, fd_set *restrict readfds,
           fd_set *restrict writefds, fd_set
*restrict exceptfds,
           struct timeval *restrict tvptr);

Returns: count of ready descriptors, 0 on timeout, 1 on error

#include <sys/select.h>

int pselect(int maxfdp1, fd_set *restrict readfds,
            fd_set *restrict writefds, fd_set
 *restrict exceptfds,
            const struct timespec *restrict tsptr,
            const sigset_t *restrict sigmask);

Returns: count of ready descriptors, 0 on timeout, 1 on error

#include <poll.h>

int poll(struct pollfd fdarray[], nfds_t nfds, int
timeout);

Returns: count of ready descriptors, 0 on timeout, 1 on error

5.异步IO

6.readv和writev函数

7.readn和writen函数

8存储映射IO

#include <sys/mman.h>

void *mmap(void *addr, size_t len, int prot, int
flag, int filedes,
           off_t off );

Returns: starting address of mapped region if OK, MAP_FAILED on error

例:用存储映射IO复制文件

#include "apue.h"
#include <fcntl.h>
#include <sys/mman.h>

int
main(int argc, char *argv[])
{
    int         fdin, fdout;
    void        *src, *dst;
    struct stat statbuf;

    if (argc != 3)
        err_quit("usage: %s <fromfile> <tofile>", argv[0]);

    if ((fdin = open(argv[1], O_RDONLY)) < 0)
        err_sys("can't open %s for reading", argv[1]);

    if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC,
      FILE_MODE)) < 0)
        err_sys("can't creat %s for writing", argv[2]);

    if (fstat(fdin, &statbuf) < 0)   /* need size of input file */
        err_sys("fstat error");

    /* set size of output file */
    if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1)
        err_sys("lseek error");
    if (write(fdout, "", 1) != 1)
        err_sys("write error");

    if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED,
      fdin, 0)) == MAP_FAILED)
        err_sys("mmap error for input");

    if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE,
      MAP_SHARED, fdout, 0)) == MAP_FAILED)
        err_sys("mmap error for output");

    memcpy(dst, src, statbuf.st_size); /* does the file copy */
    exit(0);
}

猜你喜欢

转载自brxonline.iteye.com/blog/1139524