zoukankan      html  css  js  c++  java
  • 进程间通信 IPC(Inter-Process Communication)

     

    一、管道

    管道是进程间通信中最古老的方式,所有UNIX都提供此种通信机制。管道有以下两种局限性:

    1. 历史上,他们是半双工的(即数据只能在一个方向上流动)。
    2. 管道只能在具有公共祖先的两个进程间使用。通常,一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。

    FIFO没有第二种局限性。
    尽管有这两种局限性,半双工管道仍然是最常用的IPC形式。

    管道由pipe()函数创建:

    #include <unistd.h>
    int pipe(int fd[2]);  返回值:若成功,返回0,若出错,返回-1
    参数fd返回两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。fd[1]的输出是fd[0]的输入。
    

    通常,进程会先调用pipe,接着调用fork,从而创建从父进程到子进程的IPC通道,反之亦然。fork之后做什么取决于我们想要的数据流的方向。
    对于从父进程到子进程的管道:父进程关闭管道的读端(fd[0]),子进程关闭写端(fd[1])。
    对于从子进程到父进程的管道:父进程关闭管道的写端(fd[1]),子进程关闭读端(fd[0])。

     

    二、FIFO

    FIFO有时被称为命名管道,通过FIFO,不相关的进程也能交换数据。
    FIFO由mkfifo()函数创建:

    #include <sys/stat.h>
    int mkfifo(const char *path, mode_t mode);   返回值:若成功,返回0,若出错,返回-1
    

    FIFO有如下两种用途:

    1. shell命令使用FIFO函数将数据从一条管道传送到另一条时,无需创建中间临时文件。
    2. 客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程二者之间传递数据。

     

    三、消息队列

    消息队列是消息的链接表,存储在内核中,由消息队列标识符标识。
    客户进程和服务器进程之间的双向数据流。

    msgget用于创建一个新队列或打开一个现有队列,msgsnd将新消息添加到队列尾端,每个消息包含一个正的长整型类型的字段、一个非负的长度(nbytes)以及实际数据字节数(对应于长度),msgrcv用于从队列中取消息。

    #include <sys/msg.h>
    int msgget(key_t key, int flag);  返回值:若成功,返回消息队列ID,若出错,返回-1
    int msgsnd(int msgid, const void *ptr, size_t nbytes, int flag);  返回值:若成功,返回0,若出错,返回-1
    ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);  返回值:若成功,返回消息数据部分的长度,若出错,返回-1
    

     

    四、信号量

    本质上,信号量是一个计数器,用于为多个进程提供对共享数据对象的访问。
    维护信号量状态的是Linux内核操作系统而不是用户进程。

    一般说来,为了获得共享资源,进程需要执行下列操作:

    1. 测试控制该资源的信号量。
    2. 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。
    3. 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
    4. 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。

     

    五、共享存储

    共享存储允许两个或多个进程共享一个给定的存储区。因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的一种IPC。
    通常,信号量被用来实现对共享存储数据存取的同步。(也可以用记录锁或互斥量)

    shmget获得一个共享存储标识符,shmctl对共享存储段执行多种操作,shmat将共享存储段连接到它的地址空间。

    #include<sys/shm.h>
    int shmget(key_t key, size_t size, int flag); 返回值:若成功,返回共享存储ID;若出错,返回-1
    int shmctl(int shmid, int cmd, struct shmid_ds *buf); 返回值:若成功,返回0;若出错,返回-1
    void *shmat(int shmid, const void *addr, int flag); 返回值:若成功,返回指向共享存储段的指针;若出错,返回-1
    

     

    六、网络IPC:套接字

    不同计算机(通过网络相连)上的进程相互通信的机制:网络进程间通信(network IPC)。
    套接字是通信端点的抽象。正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字。

    socket创建一个套接字,shutdown禁止一个套接字的I/O。

    #include <sys/socket.h>
    int socket(int domain, int type, int protocol);  返回值:若成功,返回文件(套接字)描述符,若出错,返回-1
    int shutdown(int sockfd, int how);  返回值:若成功,返回0,若出错,返回-1
    
  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/zengzhihua/p/9913186.html
Copyright © 2011-2022 走看看