APUE第十四章.第十五章学习笔记

来源:互联网 发布:js正则数字验证小数点 编辑:程序博客网 时间:2024/06/05 11:03

1.I/O多路转接

 /*********************************************    包含头文件:  #include <sys/select.h>    函数原型:   int select(int maxfdpl,fd_set *restrict readfds,    fd_set *restrict writefds,fd_set *restrict  exceptfds,struct    timeval *restrict tvptr);    函数说明:关心特定文件符是否可读,可写,有异常,tvptr表示愿意       等待多长时间    若tvptr为NULL  表示永久等待 (若指定条件的一个描述     符已经准备好或者捕捉到一个信号.select返回)    若tvptr→tv_sec == 0 && tvptr→tv_usec  == 0,则根本不等    待    若tvptr→tv_sec != 0 || tvptr→tv_usec != 0,则等待特定时间    (可如(1)中断);    返回值:准备就绪的描述符数目,若超时,返回0,若出错,返回-1    **********************************************/   /**********************************************    包含头文件:  #include <sys/select.h>    函数原型:   int FD_ISSET(int fd,fd_set *fdset);    返回值: 若fd在描述符集中,返回非0值,否则,返回0                void FD_CLR(int fd,fd_set* fdset);                void FD_SET(int fd,fd_set *fdset);                void FD_ZERO(int fd,fd_set *fdset);        函数说明:意同名    **********************************************/
/***************************包含头文件:  #include <sys/select.h>函数原型:   int  pselect(int maxfdpl,fd_set *restrict readfds, fd_set *restrict writefds,fd_set *restrict exceptfds,const struct timespec * restrict tsptr,const sigset_t *restrict sigmask);函数说明:可以在函数返回前屏蔽一些信号,超时控制更为精确,返回后恢复调用前屏蔽字,其他与select相同返回值:准备就绪的文件描述符,若超时,返回0,若出错,返回-1*******************************************/
/*****************************************包含头文件:  #include <poll.h>函数原型:   int poll(struct pollfd fdarray[],nfds_t nfds,int timeout);参数说明:struct pollfd{    int fd;   //文件描述符    short events;  //请求的事件    short revents;  //返回的事件};poll函数的事件标志符值常量说明POLLIN普通或优先级带数据可读POLLRDNORM普通数据可读POLLRDBAND优先级带数据可读POLLPRI高优先级数据可读POLLOUT普通数据可写POLLWRNORM普通数据可写POLLWRBAND优先级带数据可写POLLERR发生错误POLLHUP发生挂起POLLNVAL描述字不是一个打开的文件后三个写入revent当描述符被挂起(POLLHUP)就不能再写该描述符,但可能从该描述符读取数据timeout指定我们要等待的时间:timeout == -1 永远等待(准备好或捕捉到信号返回)timeout == 0   不等待(测试所有描述符并返回)timeout > 0 等待timeout毫秒(准备好或捕捉到信号返回)*****************************************/

存储映射

/*****************************************包含头文件:  #include <sys/uio.h>函数原型:   ssize_t readv(int fd,const struct iovec* iov,int iovent);            ssize_t writev(int fd,const struct iovec *iov,int iovent);函数说明:struct iovec{    void *iov_base;   //缓冲区开始地址    size_t iov_len;     //缓冲区大小};iov是指向struct iovec数组的一个指针,iovent是元素个数使用iov[0]…...iov[iovent – 1]非连续缓冲区进行I/O返回值:已读或已写的字节数,若出错,返回-1*****************************************//*****************************************包含头文件:  #include <sys/mman.h>函数原型:   void* mmap(void* addr,size_t len,int prot,int flag,int fd,off_t off);函数说明:addr参数用于指定映射存储区的起始地址,通常将其设置为0,这表示由系统分配该映射区的地址fd参数指定要被映射文件的描述符,在文件映射到地址空间前,必须打开文件len指定要映射的字节数off是要映射字节在文件中的起始偏移量prot参数指定映射存储区的保护要求:Prot                                         说明PROT_READ                     映射区可读PROT_WRITE                   映射区可写PROT_EXEC                     映射区可执行PROT_NONE                    映射区不可访问flag参数影响映射存储区的多种属性:MAP_FIXED     返回值必须等于attr(获得最大可移植性,将attr设为0)MAP_SHARED  修改映射区即修改源文件MAP_PRIVATE  映射区文件的副本,修改不会影响源文件*****************************************//*****************************************包含头文件:  #include <sys/mman.h>函数原型:   int mprotect(void* addr,size_t len,int prot);函数说明:更改映射区的权限返回值:若成功,返回0,若出错,返回-1*****************************************//*****************************************包含头文件:  #include <sys/mman.h>函数原型: int msync(void* addr,size_t len,int flags);函数说明:将映射区修改的内容冲洗到文件里flags指定为MS_SYNC时等待冲洗完毕函数才返回flags指定为MS_ASYNC时只是发出冲洗请求便返回*****************************************//*****************************************包含头文件:  #include <sys/mman.h>函数原型: int munmap(void* addr,size_t len);函数说明:解除文件与存储映射区的关系只有终止进程时或使用该函数才能解除文件与存储映射区的关系关闭文件描述符无影响返回值:若成,返回0,若出错,返回-1*****************************************/

异步I/O

/*****************************************struct aiocb{    int aio_fildes;       /*文件描述符*/    off_t aio_offset;   /*I/O时文件偏移量*/    volatile void* aio_buf; /*I/O时使用缓冲区    size_t aio_nbytes;/*转移字节数*/    int aio_reqprio;  /*属性*/    struct sigevent aio_sigevent; /*信号消息*/    int aio_lio_opcode; /*I/O操作: LIO_READ(交给aio_read处理)                        LIO_WRITE(交给aio_write处理)                         LIO_NOP(被忽略的空操作)*/};struct sigevent{    int sigev_notify;    /*通知类型*/    int sigev_signo;    /*信号*/    union sigval sigev_value;  /*通知参数*/    void (*sigev_notify_function)(union sigval)    /*通知函数*/    pthread_attr_t *sigev_notify_attributes;      /*通知属性*/};sigev_notify字段控制通知类型:SIGEV_NONE     异步I/O完成后,不通知进程SIGEV_SIGNAL  异步I/O完成后,产生sigev_signo信号SIGEV_THREAD  当异步I/O请求完成时,由sigev_notify_function字段指定的函数被调用*****************************************//****************************************包含头文件:  #include <aio.h>函数原型    int aio_read(struct aiocb *aiocb);            int aio_write(strcut aiocb *aiocb);函数说明:得到异步I/O请求,放入等待队列(返回结果与实际IO并无关系)返回值:若成功,返回0,若出错,返回-1****************************************//****************************************包含头文件:  #include <aio.h>函数原型: int aio_fsync(int op,struct aiocb* aiocb);函数说明:op设为 O_DSYNC   请求刷新文件内容                  op设为O_SYNC   等待刷新文件内容返回****************************************//****************************************包含头文件:  #include <aio.h>函数原型:  int aio_error(const struct *aiocb aiocb);函数说明: 获取异步I/O同步操作的完成状态返回值:0                      异步操作完成-1                     aio_error调用失败具体进errnoEINPROCESS 异步I/O操作还在等待其它情况                    异步操作失败返回的错误码    ****************************************//*****************************************包含头文件:  #include <aio.h>函数原型:ssize_t aio_return(const struct aiocb *aiocb);函数说明:如果异步操作完成,通过aio_return获取异步操作的返回值返回值:如果aio_return本身失败,返回-1,其他情况返回异步操作的返回值*****************************************//*****************************************包含头文件:  #include <aio.h>函数原型: int aio_suspend(const struct aiocb *const list[],int nent,const struct timespec *timeout);函数说明:如果所有事务都完成,通过aio_suspend阻塞进程直到特定异步I/O完成*****************************************//*****************************************包含头文件:  #include <aio.h>函数原型: int aio_cancel(int fd,struct aiocb* aiocb);函数说明:fd参数指定未完成的异步I/O操作文件描述符,若acb为NULL,系统将会尝试取消所有该文件上未完成的异步I/O操作返回值:AIO_ALLDONE     所有操作在尝试取消它们之前已完成AIO_CANCELED  所有要求的操作都被取消AIO_NOTCANCELED  至少有一个要求的操作没被取消*****************************************//*****************************************包含头文件:  #include <aio.h>函数原型:   int lio_listio(int mode,struct aiocb *restrict const list[restrict],int nent,struct sigevent *restrict sigev);函数说明:mode参数决定I/O是否异步LIO_WAIT               非异步LIO_NOWAIT          异步对列表进行I/O操作,sigev是所有I/O操作完成后的通知 *****************************************/

管道:

/*****************************************包含头文件:  #include <unistd.h>函数原型: int pipe(int fd[2]);函数说明:创建管道,fd[0]为读打开,fd[1]为写打开返回值:若成功,返回0,若出错,返回-1*****************************************/

vi 15.1.c

#include <stdio.h>#include <stdlib.h>#include <sys/wait.h>#include <unistd.h>#define MAXLINE 5int main(){    int fd[2];    volatile int n;    char buf[MAXLINE];    if (pipe(fd) < 0)    {    printf("pipe error\n");    exit(1);    }    pid_t pid;    if ((pid = fork()) < 0)    {    printf("fork error\n");    exit(0);    }    else if (pid == 0)    {    close(fd[1]);    n = read(fd[0],buf,n);    write(STDOUT_FILENO,buf,n);    exit(0);    }    else    {    close(fd[0]);    n = read(STDIN_FILENO,buf,MAXLINE);    write(fd[1],buf,n);    }    return 0;}

这里写图片描述

vi mywait.h

#include <unistd.h>static int fd1[2],fd2[2];void TELL_WAIT(){    if (pipe(fd1) < 0 || pipe(fd2) < 0)    {    printf("pipe error\n");    exit(1);    }}void WAIT_CHILD(){    char c;    if (read(fd1[0],&c,1) != 1)    {    printf("read error\n");    exit(1);    }}void TELL_CHILD(){    if (write(fd2[1],"c",1) < 0)    {    printf("write error\n");    exit(1);    }}void WAIT_PARENT(){    char c;    if (read(fd2[0],&c,1) < 0)    {    printf("read error\n");    exit(1);    }}void TELL_PARENT(){    if (write(fd1[1],"p",1) < 0)    {    printf("write error\n");    exit(1);    }}

vi 15.2.c

#include <stdio.h>#include <stdlib.h>#include "pipewait.h"#include <sys/wait.h>int main(){    pid_t pid;    TELL_WAIT();    if ((pid = fork()) < 0)    {    printf("fork error\n");    }    else if (pid == 0)    {    WAIT_PARENT();    printf("son is second\n");    exit(0);    }    else    {    printf("father is first\n");    TELL_CHILD();    if (waitpid(pid,NULL,0) < 0)    {        printf("waitpid error\n");        exit(0);    }    exit(0);    }    return 0;

这里写图片描述

FIFO

/*****************************************包含头文件:  #include <sys/stat.h>函数原型:   int mkfifo(const char* path,mode_t mode);            int mkfifoat(int fd,const char* path,mode_t mode);函数说明:创建一个命名管道(FIFO),FIFO是一种文件类型返回值:若成功,返回0,若出错,返回-1*****************************************/

IPC

/*****************************************包含头文件:  #include <sys/ipc.h>函数原型: key_t ftok(const char* path,int id);函数说明:由一个路径名和项目ID产生一个键返回值:若成功,返回键,若出错,返回key_t - 1*****************************************//*****************************************strcut ipc_perm{    uid_t uid;    /*用户有效用户ID*/    gid_t gid;    /*用户有效组ID*/    uid_t cuid;  /*创建者的有效用户ID*/    gid_t cgid;  /*创建者的有效组ID*/    mode_t mode; /*权限模式*/...}*****************************************//****************************************共享存储:共享存储允许两个或多个进程共享一个给定的存储区,因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的一种IPC****************************************//*****************************************共享存储:struct shmid_ds{    strcut ipc_perm shm_perm;  /*ipc 结构*/    size_t shm_segsz;;  /*共享段大小*/    pid_t shm_lpid;  /*上次调用shmop()的进程ID*/    pid_t shm_cpid; /* 创建者的进程ID*/    shmatt_t shm_nattch; /*连接(共享)数量*/    time_t shm_atime;   /*上次连接时间*/    time_t shm_dtime; /*上次分离时间*/    time_t shm_ctime;  /*上次改变时间*/};*****************************************//*****************************************包含头文件:  #include <sys/shm.h>函数原型:int shmget(key_t key,size_t size,int flag);函数说明:获得共享存储标识符返回值:若成功,返回共享存储ID,若出错,返回-1*****************************************//****************************************包含头文件:  #include <sys/shm.h>函数原型:int shmctl(int shmid,int cmd,struct shmid_ds *buf);函数说明:cmd指定运作方式:IPC_STAT    取此段的shmid_ds结构,并存储于bufIPC_SET      按buf结构的值指定shm_perm.uid,shm_perm.gid shm_perm.mode(此命令执行需要相应权限)IPC_PMID   从系统中删除该共享存储段****************************************//****************************************包含头文件:  #include <sys/shm.h>函数原型:   void* shmat(int shmid,const void* addr,int flag);函数说明:一旦创建了一个共享存储段,进程就可调用shmat将其连接到它的地址空间(addr一般指定为0)如果在flag中指定了SHM_RDONLY位,则以只读方式连接此段,否则以读写方式连接此段返回值:若成功,返回指向共享存储段的指针,若出错,返回-1****************************************//*****************************************包含头文件:  #include <sys/shm.h>函数原型: int shmdt(const void* addr);函数说明:若成功,shmdt将使相关shmid_ds结构中的shm_nattch减一*****************************************//*****************************************POSIX 信号量包含头文件:  #include <semaphore.h>函数原型: sem_t * sem_open(const char* name,int oflag,…../*mode_t mode);函数说明:创建一个信号量或引用一个现有信号量当引用一个现有信号量可以将oflag设定为0当想得到一个新的信号量可将oflag设定O_CREAT若设定为O_CREAT | O_EXCL,若信号量已存在,则sem_open调用失败返回值:若成功,返回信号量,若出错,返回SEM_FAILED*****************************************//*****************************************包含头文件:  #include <semaphore.h>函数原型: int sem_close(sem_t *sem);函数说明: 释放任何信号量相关的资源返回值:若成功,返回0,若出错,返回-1*****************************************//*****************************************包含头文件:  #include <semaphore.h>函数原型:int sem_unlink(const char* name);函数说明:删除信号量的名字,如果没有打开信号量的引用,则该信号量会被销毁,否则,销毁延迟到最后一个打开的引用关闭返回值:若成功,返回0,否则,返回-1*****************************************//*****************************************包含头文件:  #include <semaphore.h>函数原型:   int sem_trywait(sem_t *sem);            int sem_wait(sem_t *sem);函数说明:使用sem_wait时,信号量计数是0,就会发生阻塞,直到成功使信号量减一或者被信号中断时才返回若使用sem_trywait,信号量计数为0,则返回-1并将errno置为EAGAIN*****************************************//*****************************************包含头文件:  #include <semaphore.h>                #include <time.h>函数原型:sem_timewait(sem_t *restrict sem,const struct timespec *restrict tsptr);函数说明:若信号量为0,选择阻塞一段确定的时间返回值:若成功,返回0,若出错,返回-1*****************************************//*****************************************包含头文件:  #include <semaphore.h>函数原型:   int sem_post(sem_t *sem);函数说明:将信号量值增加一返回值:若成功,返回0,若出错,返回-1*****************************************/