linux中ipc_ipc linux - CSDN
  • Linux IPC总结(全)

    2011-08-02 11:27:36
    IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法...Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支
    IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法。Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支持POSIX IPC。
    

    System V,BSD,POSIX

        System V是Unix操作系统最早的商业发行版之一。它最初由AT&T(American Telephone & Telegraph)开发,最早在1983年发布。System V主要发行了4个版本,其中SVR4(System V Release 4)是最成功的版本。BSD(Berkeley Software Distribution,有时也被称为Berkeley Unix)是加州大学于1977至1995年间开发的。在19世纪八十年代至九十年代之间,System V和BSD代表了Unix的两种主要的操作风格。它们的主要区别如下:

        系统                      System V           BSD
        root脚本位置            /etc/init.d/       /etc/rc.d/
        默认shell                 Bshell             Cshell
        文件系统数据            /etc/mnttab     /etc/mtab
        内核位置                  /UNIX             /vmUnix
        打印机设备                lp                  rlp
        字符串函数                memcopy       bcopy
        终端初始化设置文件    /etc/initab       /etc/ttys
        终端控制                  termio            termios

        Linux系统的操作风格往往介于这两种风格之间。

        POSIX(Portable Operating System Interface [for Unix])是由IEEE(Institute of Electrical and Electronics Engineers,电子电气工程协会)开发的。现有的大部分Unix都遵循POSIX标准,而Linux从一开始就遵循POSIX标准。

    最初的Unix IPC

    1、信号

        信号是Unix/Linux系统在一定条件下生成的事件。信号是一种异步通信机制,进程不需要执行任何操作来等待信号的到达。信号异步通知接收信号的进程发生了某个事件,然后操作系统将会中断接收到信号的进程的执行,转而去执行相应的信号处理程序。

        (1)注册信号处理函数
            #include <signal.h>
            /*typedef void (*sighandler_t)(int);  sighandler_t signal(int signum,sighandler_t handler);*/
            * void (*signal(int signum, void (*handler)(int)))(int);  //SIG_IGN && SIG_DFL
            * int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

        (2)发送信号
            #include <signal.h>
            * int kill(pid_t pid,int sig); //#include <sys/types.h>

            * int raise(int sig);            //kill(getpid(),sig);
            * unsigned int alarm(unsigned int seconds); //(#include <unistd.h>) seconds秒后,向进程本身发送SIGALRM信号。

        (3)信号集
            信号集被定义为:typedef struct {unsigned long sig[_NSIG_WORDS];} sigset_t;
            * int sigaddset(sigset_t *set,int sig);
            * int sigemptyset(sigset_t *set);

    2、管道(Pipe)

        管道用来连接不同进程之间的数据流。

        (1)在两个程序之间传递数据的最简单的方法是使用popen()和pclose()函数:
            #include <stdio.h>
            FILE *popen(const char *command, const char *open_mode);
            int pclose(FILE *stream);

        popen()函数首先调用一个shell,然后把command作为参数传递给shell。这样每次调用popen()函数都需要启动两个进程;但是由于在Linux中,所有的参数扩展(parameter expansion)都是由shell执行的,这样command中包含的所有参数扩展都可以在command程序启动之前完成。

        (2)pipe()函数:
            #include <unistd.h>
            int pipe(int pipefd[2]);

        popen()函数只能返回一个管道描述符,并且返回的是文件流(file stream),可以使用函数fread()和fwrite()来访问。pipe()函数可以返回两个管道描述符:pipefd[0]pipefd[1],任何写入pipefd[1]的数据都可以从pipefd[0]读回;pipe()函数返回的是文件描述符(file descriptor),因此只能使用底层的read()和write()系统调用来访问。pipe()函数通常用来实现父子进程之间的通信。

        (3)命名管道:FIFO
            #include <sys/types.h>
            #include <sys/stat.h>
            int mkfifo(const char *fifo_name, mode_t mode);

        前面两种管道只能用在相关的程序之间,使用命名管道可以解决这个问题。在使用open()打开FIFO时,mode中不能包含O_RDWR。mode最常用的是O_RDONLY,O_WRONLY与O_NONBLOCK的组合。O_NONBLOCK影响了read()和write()在FIFO上的执行方式。

        PS:要想查看库函数用法,最可靠的资料来自Linux manual page:

        $sudo apt-get install manpages-dev

        $man 3 function_name

    System V IPC

        System V IPC指的是AT&T在System V.2发行版中引入的三种进程间通信工具:(1)信号量,用来管理对共享资源的访问 (2)共享内存,用来高效地实现进程间的数据共享 (3)消息队列,用来实现进程间数据的传递。我们把这三种工具统称为System V IPC的对象,每个对象都具有一个唯一的IPC标识符(identifier)。要保证不同的进程能够获取同一个IPC对象,必须提供一个IPC关键字(IPC key),内核负责把IPC关键字转换成IPC标识符。   

        System V IPC具有相似的语法,一般操作如下:

        (1)选择IPC关键字,可以使用如下三种方式:

           a)IPC_PRIVATE。由内核负责选择一个关键字然后生成一个IPC对象并把IPC标识符直接传递给另一个进程。
           b)直接选择一个关键字。
           c)使用ftok()函数生成一个关键字。

        (2)使用semget()/shmget()/msgget()函数根据IPC关键字key和一个标志flag创建或访问IPC对象。如果key是IPC_PRIVATE;或者key尚未与已经存在的IPC对象相关联且flag中包含IPC_CREAT标志,那么就会创建一个全新的IPC对象。

        (3)使用semctl()/shmctl()/msgctl()函数修改IPC对象的属性。

        (4)使用semctl()/shmctl()/msgctl()函数和IPC_RMID标志销毁IPC实例。

        System V IPC为每个IPC对象设置了一个ipc_perm结构体并在创建IPC对象的时候进行初始化。这个结构体中定义了IPC对象的访问权限和所有者:

        struct ipc_perm{
           uid_t uid;   //所有者的用户id
           gid_t gid;   //所有者的组id
           uid_t cuid;  //创建者的用户id
           gid_t cgid;  //创建者的组id
           mode_t mode; //访问模式
          
       
    };

        shell中管理IPC对象的命令是ipcs、ipcmk和ipcrm。

    1、信号量(Semaphores)

        System V的信号量集表示的是一个或多个信号量的集合。内核为每个信号量集维护一个semid_ds数据结构,而信号量集中的每个信号量使用一个无名结构体表示,这个结构体至少包含以下成员:
        struct{
            unsigned short semval;//信号量值,总是>=0
            pid_t sempid;  //上一次操作的pid
          
       
    };

        #include <sys/types.h>
        #include <sys/ipc.h>
       
    #include <sys/sem.h>
        (1)创建或访问信号量
            * int semget(key_t key,int nsems,int flag);
        nsems指定信号量集中信号量的个数,如果只是获取信号量集的标识符(而非新建),那么nsems可以为0。flag的低9位作为信号量的访问权限位,类似于文件的访问权限;如果flag中同时指定了IPC_CREAT和IPC_EXCL,那么如果key已与现存IPC对象想关联的话,函数将会返回EEXIST错误。例如,flag可以为IPC_CREAT|0666。

        (2)控制信号量集
            * int semctl(int semid,int semnum,int cmd,union semun arg);
        对semid信号量集合执行cmd操作;cmd常用的两个值是:SETVAL初始化第semnum个信号量的值为arg.val;IPC_RMID删除信号量。

        (3)对一个或多个信号量进行操作
            * int semop(int semid,struct sembuf *sops,unsigned nsops);
            * struct sembuf{
                  unsigned short sem_num;  //信号量索引
                  short   sem_op;     //对信号量进行的操作,常用的两个值为-1和+1,分别代表P、V操作
                  short   sem_flag;   //比较重要的值是SEM_UNDO:当进程结束时,相应的操作将被取消;同时,如果进程结束时没有释放资源的话,系统会自动释放
              
    };

    2、共享内存

        共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC。

        #include <sys/ipc.h>
       
    #include <sys/shm.h>
        (1)创建或访问共享内存
            * int shmget(key_t key,size_t size,int shmflg);

        (2)附加共享内存到进程的地址空间
            * void *shmat(int shmid,const void *shmaddr,int shmflg);//shmaddr通常为NULL,由系统选择共享内存附加的地址;shmflg可以为SHM_RDONLY

        (3)从进程的地址空间分离共享内存
            * int shmdt(const void *shmaddr); //shmaddr是shmat()函数的返回值

        (4)控制共享内存
            * int shmctl(int shmid,int cmd,struct shmid_ds *buf);
            * struct shmid_ds{
                  struct ipc_perm shm_perm;
                  
             
    };
        cmd的常用取值有:(a)IPC_STAT获取当前共享内存的shmid_ds结构并保存在buf中(2)IPC_SET使用buf中的值设置当前共享内存的shmid_ds结构(3)IPC_RMID删除当前共享内存

    3、消息队列

        消息队列保存在内核中,是一个由消息组成的链表。

        #include <sys/types.h>
        #include <sys/ipc.h>
       
    #include <sys/msg.h>
        (1)创建或访问消息队列
        * int msgget(key_t key,int msgflg);

        (2)操作消息队列
            * int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);
        msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小
            * ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg);
        如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值要小于等于msgtype的绝对值。

        (3)控制消息队列
            * int msgctl(int msqid,int cmd,struct msqid_ds *buf);
            * struct msqid_ds{
                  struct ipc_perm msg_perm;
                  
               };

    Socket
      套接字(Socket)是由Berkeley在BSD系统中引入的一种基于连接的IPC,是对网络接口(硬件)和网络协议(软件)的抽象。它既解决了无名管道只能在相关进程间单向通信的问题,又解决了网络上不同主机之间无法通信的问题。

      套接字有三个属性:域(domain)、类型(type)和协议(protocol),对应于不同的域,套接字还有一个地址(address)来作为它的名字。

      域(domain)指定了套接字通信所用到的协议族,最常用的域是AF_INET,代表网络套接字,底层协议是IP协议。对于网络套接字,由于服务器端有可能会提供多种服务,客户端需要使用IP端口号来指定特定的服务。AF_UNIX代表本地套接字,使用Unix/Linux文件系统实现。

      IP协议提供了两种通信手段:流(streams)和数据报(datagrams),对应的套接字类型(type)分别为流式套接字和数据报套接字。流式套接字(SOCK_STREAM)用于提供面向连接、可靠的数据传输服务。该服务保证数据能够实现无差错、无重复发送,并按顺序接收。流式套接字使用TCP协议。数据报套接字(SOCK_DGRAM)提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议。

      一种类型的套接字可能可以使用多于一种的协议来实现,套接字的协议(protocol)属性用于指定一种特定的协议。

    1
    2
    
    #include <sys/types.h>
    #include <sys/socket.h>

      (1) 创建套接字

    1
    
    int socket(int domain,int type,int protocol);

      对于SOCK_STREAM和SOCK_DGRAM而言,分别只有一种协议支持这种类型的套接字。因此protocol可以为0,表示默认的协议。
      每种套接字域都有一种对应的套接字地址。对于AF_UNIX和AF_INET,套接字地址分别为sockaddr_un和sockaddr_in,位于<sys/un.h>和<sys/in.h>中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    struct sockaddr_un{ 
        sa_family_t sun_family; //AF_UNIX
        char sun_path[];    //pathname
    };
     
    struct sockaddr_in{ 
        short int sin_family; //AF_INET 
        unsigned short int sin_port; 
        struct in_addr sin_addr;
        //...  
    };
     
    struct in_addr{ 
        unsigned long int s_addr;//可以使用inet_addr()把IP地址字符串转换成
    		//  网络字节序(network byte order,使用大端模式)的二进制数据
    };

      (2) 命名套接字

    1
    
    int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);//将无名套接字sockfd与addr绑定(bind)

      (3) 监听套接字

    1
    
    int listen(int sockfd,int backlog);//backlog限定了等待服务的队列的最大长度

      (4) 等待接受连接

    1
    
    int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);

      当客户端程序尝试连接sockfd套接字时,accept返回一个新的套接字与客户端进行通信。如果addr不是NULL,那么客户端的地址将会保存在addr所指向的结构体中;调用accept()前必须先将addrlen初始化为addr所指向结构体的大小,accept()返回以后,addrlen将会被设置成客户端套接字地址结构体的实际大小。然后,通过对accept()返回的套接字执行read()和write()操作即可实现与客户端的简单的通信。

      (5) 建立连接(客户端)

    1
    
    int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

      connect()在无名套接字sockfd和addr之间建立连接。addr指向的结构体中可以包含服务器的IP地址和端口号等信息。

      (6) 数据传输

    1
    2
    
    ssize_t send(int sockfd,const void *buf,size_t len,int flags);
    ssize_t recv(int sockfd, void *buf, size_t len,int flags);

      (7) 关闭套接字

    1
    
    int close(int fd);

      (8) 主机字节序和网络字节序的转换

    1
    2
    3
    4
    5
    
    #include <netinet/in.h>
    unsigned long int htonl(unsigned long int hostlong);  //host to network,long
    unsigned short int htons(unsigned short int hostshort);
    unsigned long int ntohl(unsigned long int netlong);
    unsigned short int ntohs(unsigned short int netshort);

      long型函数用来转换sockaddr_in.in_addr.s_addr;short型函数用来转换sockaddr_in.sin_port。

    总结:


    System V IPC API

     

    1,消息队列

    int ftok(const char *pathname, int prj_id);

    int msgget(key_t key,int msgflag);

    int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);

    int msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);

     

    2,信号量

    int semget(key_t key,int nsems,int semflag);

    int semctl(int semid,int semnum,int cmd,…);

    int semop(int semid,struct sembuf *sops,unsigned nsops,struct timespec *timeout);

     

    3,共享内存

    int shmget(key_t key,size_t size,int shmflag);

    int shmctl(int shmid,int cmd,struct shmid_ds *buf);

      

    POSIX IPC API

    (省略)

     

     

     

     


    展开全文
  • LinuxIPC总结

    2018-04-08 22:50:49
     IPC:interprocess communication-进程间通信 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程间不能互相访问,要交换...

    1、什么是IPC?

        IPC:interprocess communication-进程间通信

        Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程间不能互相访问,要交换数据必须通过内核,在内核中开辟一块缓存区,进程1把数据从用户空间拷贝到内存缓冲区,进程2再从内存缓冲区中把数据读走,内核提供的这种机制称为进程间通信(IPC)。

    2、进程间通信的实质?

        不同的两个程序虽然0-4G内存地址空间不同,但两个程序的内核区在物理内存上是同一块。共享(物理内存中)同一内核区。——两个程序打开同一个文件,系统会在内核区维护打开文件的结构体,两个程序打开的是同一个结构体。

    3、有哪些常用的进程间通信方法?

        ①匿名管道(PIPE)和有名管道(FIFO):最简单

        ②信号(SIGNAL):系统的开销最小

        ③共享映射区(MMAP):可以在无血缘关系的进程间通信

        ④本地套接字(SOCKET):最稳定(但是比较复杂)

    4、为什么要进行进程间通信呢?

        两个进程间要传送数据。在接触IPC前,我们可以用文件来实现进程间通信,两个进程共享同一个打开的文件结构体。A进程写数据到文件中,B进程也打开同一个文件,内核会在内核区域维护一个打开文件的结构体,所以B可以从这个文件中读数据,但是A和B的0-4G进程地址空间是不一样的。之所以能用文件完成上面的通信,依赖于A和B他们的内核区在物理内存上是同一块。

    5、IPC方法比较

        pipe-优点:实现简单;缺点:单向通信,只能用于有血缘关系进程间。

        fifo-优点:可以在非血缘关系进程间。

        信号-优点:开销小。

        共享内存-优点:可以用于非血缘关系进程间;缺点:比较复杂。

        本地套接字-优点:稳定性好;缺点:实现复杂。

        共享内存和fifo的区别:在于数据是否可以反复读取;fifo是用队列实现的,不能反复读取;共享内存是Linux内核借助缓冲区,通过内存来实现,可以反复读取。

    展开全文
  • linux各种IPC机制

    2019-06-30 06:45:58
    docker的资源隔离,一种就是IPC的隔离。IPC是进程间通信。... 原帖发表在IBM的developerworks网站上,是一个系列的文章,作者郑彦兴,通过讲解和例子演示了Linux中几种IPC的使用方式,我觉得很好,在这里做一...

      docker中的资源隔离,一种就是IPC的隔离。IPC是进程间通信。

           下面的文章转载自https://blog.csdn.net/yyq_9623/article/details/78794775

     

           原帖发表在IBM的developerworks网站上,是一个系列的文章,作者郑彦兴,通过讲解和例子演示了Linux中几种IPC的使用方式,我觉得很好,在这里做一个保留,能看完的话Linux IPC的基础是没有问题的了。
           一)Linux环境进程间通信(一)管道及有名管道
           http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/
           二)Linux环境进程间通信(二): 信号
           上:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
           下:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html
           三)Linux环境进程间通信(三)消息队列
           http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/
           四)Linux环境进程间通信(四)信号灯
           http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
           五)Linux环境进程间通信(五): 共享内存
           上:http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html
           下:http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html

           六)Linux环境进程间通信(六): socket

           http://www.ibm.com/developerworks/cn/linux/l-ipc/

     

    ==============================================================================================

     

           linux下进程间通信的几种主要手段简介:


           管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
           信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
           报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及  缓冲区大小受限等缺点。
           共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
           信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
           套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

           管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。一般文件的I/O函数都可以用于管道,如close、read、write等等。

           管道的主要局限性正体现在它的特点上:


           只支持单向数据流;
           只能用于具有亲缘关系的进程之间;
           没有名字;
           管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);
           管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等;

           管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读       总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。

           管道常用于两个方面:(1)在shell中时常会用到管道(作为输入输入的重定向),在这种应用方式下,管道的创建对于用户来说是透明的;(2)用于具有亲缘关系的进程间通信,用户自己创建管道,并完成读写操作。

           FIFO可以说是管道的推广,克服了管道无名字的限制,使得无亲缘关系的进程同样可以采用先进先出的通信机制进行通信。

           管道和FIFO的数据是字节流,应用程序之间必须事先确定特定的传输"协议",采用传播具有特定意义的消息。

           要灵活应用管道及FIFO,理解它们的读写规则是关键。

    一、信号及信号来源

           信号本质

           信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

           信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。

           信号来源

           信号事件的发生有两个来源:硬件来源(比如我们按下了键盘或者其它硬件故障);软件来源,最常用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操作。

     

    三、进程对信号的响应

           进程可以通过三种方式来响应一个信号:(1)忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP;(2)捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数;(3)执行缺省操作,Linux对每种信号都规定了默认操作,详细情况请参考[2]以及其它资料。注意,进程对实时信号的缺省反应是进程终止。

           Linux究竟采用上述三种方式的哪一个来响应信号,取决于传递给相应API函数的参数。

    一、信号生命周期

           从信号发送到信号处理函数的执行完毕

           对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个重要事件来刻画:信号诞生;信号在进程中注册完毕;信号在进程中的注销完毕;信号处理函数执行完毕。相邻两个事件的时间间隔构成信号生命周期的一个阶段。

    linux IPC快餐(转) - xsh8637 - 第七天堂

     

           消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点。作为早期unix通信机制之一的信号能够传送的信息量有限,后来虽然POSIX 1003.1b在信号的实时性方面作了拓广,使得信号在传递信息量方面有了相当程度的改进,但是信号这种通信方式更像"即时"的通信方式,它要求接受信号的进程在某个时间范围内对信号做出反应,因此该信号最多在接受信号进程的生命周期内才有意义,信号所传递的信息是接近于随进程持续的概念(process-persistent),见 附录 1;管道及有名管道及有名管道则是典型的随进程持续IPC,并且,只能传送无格式的字节流无疑会给应用程序开发带来不便,另外,它的缓冲区大小也受到限制。

           消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的(参见 附录 1)。

     

    三、消息队列的限制

           每个消息队列的容量(所能容纳的字节数)都有限制,该值因系统不同而不同。

    小结:

           消息队列与管道以及有名管道相比,具有更大的灵活性,首先,它提供有格式字节流,有利于减少开发人员的工作量;其次,消息具有类型,在实际应用中,可作为优先级使用。这两点是管道以及有名管道所不能比的。同样,消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。

     


           信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。除了用于访问控制外,还可用于进程同步。

    一、信号灯概述

           信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。除了用于访问控制外,还可用于进程同步。信号灯有以下两种类型:


    二值信号灯:最简单的信号灯形式,信号灯的值只能取0或1,类似于互斥锁。
           注:二值信号灯能够实现互斥锁的功能,但两者的关注内容不同。信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。
    计算信号灯:信号灯的值可以取任意非负值(当然受内核本身的约束)。

    五、信号灯的限制

           1、 一次系统调用semop可同时操作的信号灯数目SEMOPM,semop中的参数nsops如果超过了这个数目,将返回E2BIG错误。SEMOPM的大小特定与系统,redhat 8.0为32。

           2、 信号灯的最大数目:SEMVMX,当设置信号灯值超过这个限制时,会返回ERANGE错误。在redhat 8.0中该值为32767。

           3、 系统范围内信号灯集的最大数目SEMMNI以及系统范围内信号灯的最大数目SEMMNS。超过这两个限制将返回ENOSPC错误。redhat 8.0中该值为32000。

           4、 每个信号灯集中的最大信号灯数目SEMMSL,redhat 8.0中为250。 SEMOPM以及SEMVMX是使用semop调用时应该注意的;SEMMNI以及SEMMNS是调用semget时应该注意的。SEMVMX同时也是semctl调用应该注意的。

     


           共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

           采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。

           Linux的2.2.x内核支持多种共享内存方式,如mmap()系统调用,Posix共享内存,以及系统V共享内存。linux发行版本如Redhat 8.0支持mmap()系统调用及系统V共享内存,但还没实现Posix共享内存,本文将主要介绍mmap()系统调用及系统V共享内存API的原理及应用。

     

    二、mmap()及其相关系统调用

           mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

           注:实际上,mmap()系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。

    结论:

           共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制。共享内存可以通过mmap()映射普通文件(特殊情况下还可以采用匿名映射)机制实现,也可以通过系统V共享内存机制实现。应用接口和原理很简单,内部机制复杂。为了实现更安全通信,往往还与信号灯等同步机制共同使用。

           共享内存涉及到了存储管理以及文件系统等方面的知识,深入理解其内部机制有一定的难度,关键还要紧紧抓住内核使用的重要数据结构。系统V共享内存是以文件的形式组织在特殊文件系统shm中的。通过shmget可以创建或获得共享内存的标识符。取得共享内存标识符后,要通过shmat将这个内存区映射到本进程的虚拟地址空间。

           一个套接口可以看作是进程间通信的端点(endpoint),每个套接口的名字都是唯一的(唯一的含义是不言而喻的),其他进程可以发现、连接并且与之通信。通信域用来说明套接口通信的协议,不同的通信域有不同的通信协议以及套接口的地址结构等等,因此,创建一个套接口时,要指明它的通信域。比较常见的是unix域套接口(采用套接口机制实现单机内的进程间通信)及网际通信域。

     

    5、网络编程中的其他重要概念

           下面列出了网络编程中的其他重要概念,基本上都是给出这些概念能够实现的功能,读者在编程过程中如果需要这些功能,可查阅相关概念。

    (1)、I/O复用的概念

           I/O复用提供一种能力,这种能力使得当一个I/O条件满足时,进程能够及时得到这个信息。I/O复用一般应用在进程需要处理多个描述字的场合。它的一个优势在于,进程不是阻塞在真正的I/O调用上,而是阻塞在select()调用上,select()可以同时处理多个描述字,如果它所处理的所有描述字的I/O都没有处于准备好的状态,那么将阻塞;如果有一个或多个描述字I/O处于准备好状态,则select()不阻塞,同时会根据准备好的特定描述字采取相应的I/O操作。

    (2)、Unix通信域

           前面主要介绍的是PF_INET通信域,实现网际间的进程间通信。基于Unix通信域(调用socket时指定通信域为PF_LOCAL即可)的套接口可以实现单机之间的进程间通信。采用Unix通信域套接口有几个好处:Unix通信域套接口通常是TCP套接口速度的两倍;另一个好处是,通过Unix通信域套接口可以实现在进程间传递描述字。所有可用描述字描述的对象,如文件、管道、有名管道及套接口等,在我们以某种方式得到该对象的描述字后,都可以通过基于Unix域的套接口来实现对描述字的传递。接收进程收到的描述字值不一定与发送进程传递的值一致(描述字是特定于进程的),但是特们指向内核文件表中相同的项。

    (3)、原始套接口

           原始套接口提供一般套接口所不提供的功能:


           原始套接口可以读写一些用于控制的控制协议分组,如ICMPv4等,进而可实现一些特殊功能。
           原始套接口可以读写特殊的IPv4数据包。内核一般只处理几个特定协议字段的数据包,那么一些需要不同协议字段的数据包就需要通过原始套接口对其进行读写;
           通过原始套接口可以构造自己的Ipv4头部,也是比较有意思的一点。

     

           创建原始套接口需要root权限。

    (4)、对数据链路层的访问

           对数据链路层的访问,使得用户可以侦听本地电缆上的所有分组,而不需要使用任何特殊的硬件设备,在linux下读取数据链路层分组需要创建SOCK_PACKET类型的套接口,并需要有root权限。

    (5)、带外数据(out-of-band data)

           如果有一些重要信息要立刻通过套接口发送(不经过排队),请查阅与带外数据相关的文献。

    (6)、多播

           linux内核支持多播,但是在默认状态下,多数linux系统都关闭了对多播的支持。因此,为了实现多播,可能需要重新配置并编译内核。具体请参考[4]及[2]。

           结论:linux套接口编程的内容可以说是极大丰富,同时它涉及到许多的网络背景知识,有兴趣的读者可在[2]中找到比较系统而全面的介绍。

           至此,本专题系列(linux环境进程间通信)全部结束了。实际上,进程间通信的一般意义通常指的是消息队列、信号灯和共享内存,可以是posix的,也可以是SYS v的。本系列同时介绍了管道、有名管道、信号以及套接口等,是更为一般意义上的进程间通信机制。

    转载于:https://www.cnblogs.com/lnlvinso/p/10872512.html

    展开全文
  • Linux IPC总结

    2016-08-04 18:43:10
    IPC进程间通信(Inter-Process Communication...Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支持POSIX IPC。 System V,BSD,POSIX  

    原文地址:http://www.cn

    IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法。Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支持POSIX IPC。

    System V,BSD,POSIX

        System V是Unix操作系统最早的商业发行版之一。它最初由AT&T(American Telephone & Telegraph)开发,最早在1983年发布。System V主要发行了4个版本,其中SVR4(System V Release 4)是最成功的版本。BSD(Berkeley Software Distribution,有时也被称为Berkeley Unix)是加州大学于1977至1995年间开发的。在19世纪八十年代至九十年代之间,System V和BSD代表了Unix的两种主要的操作风格。它们的主要区别如下:

        系统                      System V           BSD
        root脚本位置            /etc/init.d/       /etc/rc.d/
        默认shell                 Bshell             Cshell
        文件系统数据            /etc/mnttab     /etc/mtab
        内核位置                  /UNIX             /vmUnix
        打印机设备                lp                  rlp
        字符串函数                memcopy       bcopy
        终端初始化设置文件    /etc/initab       /etc/ttys
        终端控制                  termio            termios

        Linux系统的操作风格往往介于这两种风格之间。

        POSIX(Portable Operating System Interface [for Unix])是由IEEE(Institute of Electrical and Electronics Engineers,电子电气工程协会)开发的。现有的大部分Unix都遵循POSIX标准,而Linux从一开始就遵循POSIX标准。

    最初的Unix IPC

    1、信号

        信号是Unix/Linux系统在一定条件下生成的事件。信号是一种异步通信机制,进程不需要执行任何操作来等待信号的到达。信号异步通知接收信号的进程发生了某个事件,然后操作系统将会中断接收到信号的进程的执行,转而去执行相应的信号处理程序。

        (1)注册信号处理函数
            #include <signal.h>
            /*typedef void (*sighandler_t)(int);  sighandler_t signal(int signum,sighandler_t handler);*/
            * void (*signal(int signum, void (*handler)(int)))(int);  //SIG_IGN && SIG_DFL
            * int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

        (2)发送信号
            #include <signal.h>
            * int kill(pid_t pid,int sig); //#include <sys/types.h> 
            * int raise(int sig);            //kill(getpid(),sig);
            * unsigned int alarm(unsigned int seconds); //(#include <unistd.h>) seconds秒后,向进程本身发送SIGALRM信号。

        (3)信号集
            信号集被定义为:typedef struct {unsigned long sig[_NSIG_WORDS];} sigset_t;
            * int sigaddset(sigset_t *set,int sig);
            * int sigemptyset(sigset_t *set);

    2、管道(Pipe)

        管道用来连接不同进程之间的数据流。

        (1)在两个程序之间传递数据的最简单的方法是使用popen()和pclose()函数:
            #include <stdio.h>
            FILE *popen(const char *command, const char *open_mode);
            int pclose(FILE *stream);

        popen()函数首先调用一个shell,然后把command作为参数传递给shell。这样每次调用popen()函数都需要启动两个进程;但是由于在Linux中,所有的参数扩展(parameter expansion)都是由shell执行的,这样command中包含的所有参数扩展都可以在command程序启动之前完成。

        (2)pipe()函数:
            #include <unistd.h>
            int pipe(int pipefd[2]);

        popen()函数只能返回一个管道描述符,并且返回的是文件流(file stream),可以使用函数fread()和fwrite()来访问。pipe()函数可以返回两个管道描述符:pipefd[0]pipefd[1],任何写入pipefd[1]的数据都可以从pipefd[0]读回;pipe()函数返回的是文件描述符(file descriptor),因此只能使用底层的read()和write()系统调用来访问。pipe()函数通常用来实现父子进程之间的通信。

        (3)命名管道:FIFO
            #include <sys/types.h>
            #include <sys/stat.h>
            int mkfifo(const char *fifo_name, mode_t mode);

        前面两种管道只能用在相关的程序之间,使用命名管道可以解决这个问题。在使用open()打开FIFO时,mode中不能包含O_RDWR。mode最常用的是O_RDONLY,O_WRONLY与O_NONBLOCK的组合。O_NONBLOCK影响了read()和write()在FIFO上的执行方式。

        PS:要想查看库函数用法,最可靠的资料来自Linux manual page:

        $sudo apt-get install manpages-dev

        $man 3 function_name

     

    System V IPC

        System V IPC指的是AT&T在System V.2发行版中引入的三种进程间通信工具:(1)信号量,用来管理对共享资源的访问 (2)共享内存,用来高效地实现进程间的数据共享 (3)消息队列,用来实现进程间数据的传递。我们把这三种工具统称为System V IPC的对象,每个对象都具有一个唯一的IPC标识符(identifier)。要保证不同的进程能够获取同一个IPC对象,必须提供一个IPC关键字(IPC key),内核负责把IPC关键字转换成IPC标识符。   

        System V IPC具有相似的语法,一般操作如下:

        (1)选择IPC关键字,可以使用如下三种方式:

           a)IPC_PRIVATE。由内核负责选择一个关键字然后生成一个IPC对象并把IPC标识符直接传递给另一个进程。
           b)直接选择一个关键字。
           c)使用ftok()函数生成一个关键字。

        (2)使用semget()/shmget()/msgget()函数根据IPC关键字key和一个标志flag创建或访问IPC对象。如果key是IPC_PRIVATE;或者key尚未与已经存在的IPC对象相关联且flag中包含IPC_CREAT标志,那么就会创建一个全新的IPC对象。

        (3)使用semctl()/shmctl()/msgctl()函数修改IPC对象的属性。

        (4)使用semctl()/shmctl()/msgctl()函数和IPC_RMID标志销毁IPC实例。

        System V IPC为每个IPC对象设置了一个ipc_perm结构体并在创建IPC对象的时候进行初始化。这个结构体中定义了IPC对象的访问权限和所有者:

        struct ipc_perm{
           uid_t uid;   //所有者的用户id
           gid_t gid;   //所有者的组id
           uid_t cuid;  //创建者的用户id
           gid_t cgid;  //创建者的组id
           mode_t mode; //访问模式
           …
        
    };

        shell中管理IPC对象的命令是ipcs、ipcmk和ipcrm。

    1、信号量(Semaphores)

        System V的信号量集表示的是一个或多个信号量的集合。内核为每个信号量集维护一个semid_ds数据结构,而信号量集中的每个信号量使用一个无名结构体表示,这个结构体至少包含以下成员:
        struct{
            unsigned short semval;//信号量值,总是>=0
            pid_t sempid;  //上一次操作的pid
           …
        
    };

        #include <sys/types.h>
        #include <sys/ipc.h>
        
    #include <sys/sem.h>
        (1)创建或访问信号量
            * int semget(key_t key,int nsems,int flag); 
        nsems指定信号量集中信号量的个数,如果只是获取信号量集的标识符(而非新建),那么nsems可以为0。flag的低9位作为信号量的访问权限位,类似于文件的访问权限;如果flag中同时指定了IPC_CREAT和IPC_EXCL,那么如果key已与现存IPC对象想关联的话,函数将会返回EEXIST错误。例如,flag可以为IPC_CREAT|0666。

        (2)控制信号量集
            * int semctl(int semid,int semnum,int cmd,union semun arg);
        对semid信号量集合执行cmd操作;cmd常用的两个值是:SETVAL初始化第semnum个信号量的值为arg.val;IPC_RMID删除信号量。

        (3)对一个或多个信号量进行操作
            * int semop(int semid,struct sembuf *sops,unsigned nsops);
            * struct sembuf{
                  unsigned short sem_num;  //信号量索引
                  short   sem_op;     //对信号量进行的操作,常用的两个值为-1和+1,分别代表P、V操作
                  short   sem_flag;   //比较重要的值是SEM_UNDO:当进程结束时,相应的操作将被取消;同时,如果进程结束时没有释放资源的话,系统会自动释放
               
    };

    2、共享内存

        共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC。

        #include <sys/ipc.h>
        
    #include <sys/shm.h>
        (1)创建或访问共享内存
            * int shmget(key_t key,size_t size,int shmflg);

        (2)附加共享内存到进程的地址空间
            * void *shmat(int shmid,const void *shmaddr,int shmflg);//shmaddr通常为NULL,由系统选择共享内存附加的地址;shmflg可以为SHM_RDONLY

        (3)从进程的地址空间分离共享内存
            * int shmdt(const void *shmaddr); //shmaddr是shmat()函数的返回值

        (4)控制共享内存
            * int shmctl(int shmid,int cmd,struct shmid_ds *buf);
            * struct shmid_ds{
                  struct ipc_perm shm_perm;
                  …
              
    }; 
        cmd的常用取值有:(a)IPC_STAT获取当前共享内存的shmid_ds结构并保存在buf中(2)IPC_SET使用buf中的值设置当前共享内存的shmid_ds结构(3)IPC_RMID删除当前共享内存

    3、消息队列

        消息队列保存在内核中,是一个由消息组成的链表。

        #include <sys/types.h>
        #include <sys/ipc.h>
        
    #include <sys/msg.h>
        (1)创建或访问消息队列
        * int msgget(key_t key,int msgflg);

        (2)操作消息队列
            * int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);
        msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小
            * ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg);
        如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值要小于等于msgtype的绝对值。

        (3)控制消息队列
            * int msgctl(int msqid,int cmd,struct msqid_ds *buf);
            * struct msqid_ds{
                  struct ipc_perm msg_perm;
                  …
               };

    Socket
      套接字(Socket)是由Berkeley在BSD系统中引入的一种基于连接的IPC,是对网络接口(硬件)和网络协议(软件)的抽象。它既解决了无名管道只能在相关进程间单向通信的问题,又解决了网络上不同主机之间无法通信的问题。

      套接字有三个属性:域(domain)、类型(type)和协议(protocol),对应于不同的域,套接字还有一个地址(address)来作为它的名字。

      域(domain)指定了套接字通信所用到的协议族,最常用的域是AF_INET,代表网络套接字,底层协议是IP协议。对于网络套接字,由于服务器端有可能会提供多种服务,客户端需要使用IP端口号来指定特定的服务。AF_UNIX代表本地套接字,使用Unix/Linux文件系统实现。

      IP协议提供了两种通信手段:流(streams)和数据报(datagrams),对应的套接字类型(type)分别为流式套接字和数据报套接字。流式套接字(SOCK_STREAM)用于提供面向连接、可靠的数据传输服务。该服务保证数据能够实现无差错、无重复发送,并按顺序接收。流式套接字使用TCP协议。数据报套接字(SOCK_DGRAM)提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议。

      一种类型的套接字可能可以使用多于一种的协议来实现,套接字的协议(protocol)属性用于指定一种特定的协议。

    总结:

     

     

     

    System V IPC API

     

    1,消息队列

    int ftok(const char *pathname, int prj_id);

    int msgget(key_t key,int msgflag);

    int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);

    int msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);

     

    2,信号量

    int semget(key_t key,int nsems,int semflag);

    int semctl(int semid,int semnum,int cmd,…);

    int semop(int semid,struct sembuf *sops,unsigned nsops,struct timespec *timeout);

     

    3,共享内存

    int shmget(key_t key,size_t size,int shmflag);

    int shmctl(int shmid,int cmd,struct shmid_ds *buf);

      

    POSIX IPC API

    blogs.com/wangkangluo1/archive/2012/05/14/2498786.html
    展开全文
  • 其实IPC不仅仅只是进程间的通信,它更广泛的意义,应该是,Linux中的不同的执行体之间的通信方式。 那么要搞明白IPC,首先就要搞明白,在Linux中,到底都有哪些执行体,只有明白了执行体以及不同的执行体之间的区别...

    IPC,inter process communication,进程间通信,顾名思义。其实IPC不仅仅只是进程间的通信,它更广泛的意义,应该是,Linux中的不同的执行体之间的通信方式。

    那么要搞明白IPC,首先就要搞明白,在Linux中,到底都有哪些执行体,只有明白了执行体以及不同的执行体之间的区别,才会更深入明白不同的IPC之间的优劣。

    这里执行体的概念,指的是Linux中能够独立作为调度单位,独自占有CPU的执行时间的代码序列。

    下面简单的列出Linux中都有哪些执行体呢?

    内核空间

    (1)kthread

    (2)Work queue

    (3)soft irq

    (4)Tasklet

    (5)IRQ

    (6)Timer

    用户空间

    (1)Process

    (2)thread


    接下来的章节中,会详细的介绍这些执行体。

    展开全文
  • linux中IPC

    2014-01-05 08:55:51
    一.IPC背景 进程之间需要同步处理,同步需要通信,普通文件就是最基本的通信手段。普通文件IPC有一个进程改变另一个进程无法感知这种改变的问题。 解决办法:用特殊的文件:管道文件。 二.管道文件 1.创建管道文件 ...
  • linux中,可以使用IPC对象来进行进程间通信。IPC对象存在于内核,多进程可以操作同一个IPC对象。每个IPC对象都有一个唯一的编号,该编号是由系统分配的。那么不同的进程如何知道这个编号,进而通过它进行通信呢...
  • IPC机制:Inter-Process Communication,进程间通信机制 本文简述的IPC机制有:管道pipe、命名管道FIFO、信号、信号量、消息队列、共享内存、内存映射 1、管道pipe pipe又叫无名管道,用于一个进程及其亲属进程...
  • Linux内核中IPC全名称之为进程间通信机制,共分为多种,如下: 信号量 共享内存 消息队列 管道 信号 套接字通信 每一种实现都有其独特特性,一下博客我们会讲解其中的分类,作用以及优缺点。 分类: 1.分类 ...
  • 进程间通信(IPC)介绍 关于无名管道pipe调用的fork()方法
  • linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。...
  • linuxIPC配置

    2016-09-23 15:22:47
    ipc
  • Linux IPC之共享内存

    2011-08-25 11:52:49
    共享内存(shared memory)是最简单的Linux进程间通信方式之一。使用共享内存,不同进程可以对同一块内存进行读写。由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,...
  • linux系统IPC浅谈

    2015-11-14 00:07:57
    IPC作为进程间通讯的重要工具,被分为管道(无名管道),FIFO(又名管道),共享内存,信号量和消息队列。 1. 管道(pipe):我们一般提到的管道默认是无名管道,有以下几个特点: -> a. 管道具有单向性(半双功性),...
  • Linux进程通信的源头  linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T(原为American Telephone & Telegraph的缩写,也是中文译名美国电话电报公司...
  • linux内核IPC机制

    2017-11-02 14:05:14
    本文将从一个实例出发,逐步剖析linux内核是如何实现信号量机制的.
  • linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。...
  • linux 系统有很多进程,免不了进程间进行通信,即IPC通信,linux 有6种方式 信号、无名管道(pipe)和有名管道(FIFO)、共享内存、信号量、消息队列、套接字(socket) socket 已经在前面研究tcp/udp的时候学习过...
  • 利用Unix/LinuxIPC机制仿真一个音乐厅门票订售系统。 具体要求: 该系统包含若干售票代理,这些代理连接到一个票务中心计算机。 每个代理可以看成是一个可并发执行的进程。因此,对同一个座位的订/售动作显然是...
1 2 3 4 5 ... 20
收藏数 70,499
精华内容 28,199
关键字:

linux中ipc