zoukankan      html  css  js  c++  java
  • Chapter 17 高级进程间通信

    这章属于高级内容 内容比较简略

    1.基于STREAMS的管道

    流管道是一个双向(全双工)管道。单个流管道就能向父、子进程提供双向的数据流

    1).命名的STREAMS管道

    我们可以用fattach函数来在文件系统给一个STREAMS管道一个名字

    #include <stropts.h>
    
    int fattach(int filedes, const char *path);
    //成功返回0,错误返回-1。

    path参数必须引用一个已有的文件,调用进程必须拥有这个文件,或有对它有写的权限,或使用超级用户特权运行。

    一个进程可以调用fdetach来撤消STREAMS文件和文件系统里的名字之间的关联关系。

    #include <stropts.h>
    
    int fdetach(const cha *path);
    //成功返回0,错误返回-1。

    在fdetach被调用后,任何通过打开path而有STREAMS管道的访问的进程将仍继续访问这个流,但是后续的path打开会访问在文件系统里的原始文件。

    2).唯一连接

    在将一个STREAMS管道连接到文件系统的一个名字之前,服务器进程可将connld模块推到要被附加的管道那端。这导致下图所示的配置。


    2.Unix域套接字

    UNIX域套接字被用来和同一机器上运行的进程通信。尽管因特网域套接字可以用作同样的目的,然而UNIX域套接字更高效。

    可以使用面向网络的套接字接口来使用它们,或者你可以使用socketpair函数然创建一对没有名字的、连接的UNIX域套接字。

    #include <sys/socket.h>
    
    int socketpair(int domain, int type, int protocol, int sockfd[2]);
    //成功返回0,错误返回-1。

    1).命名UNIX域套接字

    2).唯一连接

    3.传递文件描述符

    下面三个函数可以发送和接收文件描述符

    #include "apue.h"
    
    int send_fd(int fd, int fd_to_send);
    int send_err(int fd, int status, const char *errmsg);
    //成功返回0,错误返回-1。
    
    int recv_fd(int fd, ssize_t (*userfunc)(int, const void *, size_t));
    //成功返回文件描述符,错误返回负值。

    当一个进程(通常是服务器)希望将一个描述符传送给另一个进程时,它调用send_fd或send_err。等待接收描述符的进程(客户机)调用recv_fd。

    send_fd经由fd代表的STREAM管道或UNIX域套接字发送描述符fd_to_send

    send_err 经由用fd发送errmsg和status字节。status的值应在-1 ~-2 5 5之间

    1).经由基于STREAMS的管道来传递文件描述符

        文件描述符使用两个ioctl命令经由STREAMS管道交换,这两个命令是:I_SENDFD和I_RECVFD

    2)经由UNIX域套接字来传递文件描述符

       为了用UNIX域套接字交换文件描述符,我们调用sendmsg和recvmsg函数,涉及下面的函数和结构体(详见UNP)

       下面三个宏被用来访问控制数据,一个宏用来帮助计算用于cmsg_len的值

    #include <sys/socket.h>
    
    unsigned char *CMSG_DATA(struct cmsghdr *cp);
    //返回和cmsghdr结构体相关的数据的指针。
    
    struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mp);
    //返回和msghdr结构体相关联的第一个cmsghdr结构体的指针,或者没有一个存在时返回NULL。
    
    struct cmsghdr *CMSG_NXTHDR(struct msghdr *mp, struct cmsghdr *cp);
    //给定当前cmsghdr结构体,返回和msghdr结构体相关联的下一个cmsghdr结构体的指针,或我们已经在最后一个上时返回NULL
    
    unsigned int CMSG_LEN(unsigned int nbytes);
    //返回为nbytes大的数据对象分配的尺寸。

    其中msghdr和cmsghdr结构体,这两个结构体对数据传送进行了控制

    struct msghdr {
      void         *msg_name;              /* optional address */
      socklen_t    msg_namelen;            /* address size in bytes */
      struct       iovec  *msg_iov;        /* array of I/O buffers */
      int          msg_iovlen;             /* number of elements in array */
      void         *msg_control;           /* ancillary data */
      socklen_t    msg_controllen;         /* number of ancillary bytes */
      int          msg_flags;              /* flags for received message */
    
    };
    
    
    struct cmsghdr {
      socklen_t  cmsg_len;     /* data byte count, including header */
      int        cmsg_level;   /* originating protocol */
      int        cmsg_type;    /* protocol-specific type */
      /* followed by the actual control message data */
    };
  • 相关阅读:
    设计模式享元模式实现C++
    并查集
    设计模式代理模式实现C++
    设计模式装饰模式实现C++
    最小生成树Prim算法实现
    图的邻接矩阵存储
    威佐夫博弈(Wythoff Game)初识 HDU 1527 POJ 1067
    设计模式原型模式实现C++
    三种经典博弈问题 BashGame;WythoffGame;NimmGame;
    设计模式外观模式实现C++
  • 原文地址:https://www.cnblogs.com/biyeymyhjob/p/2623403.html
Copyright © 2011-2022 走看看