• 进程间通信 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
    
  • 相关阅读:
    Python: execute an external program (zz)
    Python notes
    Web Monitor/Dev/Test Tool Collection 网站/网页监控/开发/测试工具集合
    SilkTest 2006 sp2 Notes of GettingStartedTutorial (2008,07)
    Software Testing Essentials 软件测试精要
    Flex notes
    Review Java advanced features
    Fedora 11 Configuration and Management
    进制转换的方法原理
    win32 透明置顶
  • 原文地址:https://www.cnblogs.com/zengzhihua/p/9913186.html
Copyright © 2020-2023  润新知