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

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调用失败具体进errno
EINPROCESS 异步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 5


int 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结构,并存储于buf
IPC_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
*****************************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值