zoukankan      html  css  js  c++  java
  • UNIX标准C

    一、基本概念

        进程间通信IPC:进程之间交换数据的过程叫进程间通信

        进程间同性的方式:

            简单的进程间的通信:

                命令行:父进程通过exec函数创建子进程是可以附加一些数据

                环境变量表:父进程通过exec函数创建子进程顺便传递一张环境变量表

                信号:父子进程之间可以根据进程号相互发送信号,进行简单通信

                文件:一个进程向文件中写入数据,另一个进程从文件读3出来

                命令行、环境变量只能单向传递,信号太过于简单,文件不能实时。

        传统的进程之间通信方式:管道

    二、管道

            1.管道是一种古老的通信方式(基本上不再使用)

            2.早期的管道是一种半双工,现在基本上是全双工的

            3.有名管道(这种管道是文件方式存在的)

                创建管道文件:

                    命令:mkfifo   

                    函数:int mkfifo(const char *pathname, mode_t mode);

       

            管道通信的编程模式:

                    进程a                        进程b

                    创建管道mkfifo             

                    打开管道文件open               打开管道open

                    /读数据read/write           读/写数据read/write

                    关闭管道                      关闭管道

                        

            4.无名管道:由内核帮助创建,只返回管道的文件描述符,看不到管道文件。但这种管道只能使用于fork()创建的父子进程之间。

                    int pipe(int pipefd[2])

                    pipefd[0] 用来读数据

                    pipefd[1] 用来写数据

                   

        XSI通信方式:X/open 计算机制造商组织。

             共享内存、消息队列、信号量

             

    三、XSI IPC进程间通信

        1.XSI通信是靠内核的IPC对象进程通信

        2.每一个IPC对象都有一个IPC标示(类似文件描述符),它是一个非负整数。

        3.IPC对象必须要先创建,创建完才能进行获取、设置、操作、删除。

        4.创建IPC对象必须要提供一个健值(key_t),健值是创建、获取IPC对象的依据。

        5.产生健值的方式:

            固定的字面符:1980014

            使用函数计算:健值 = ftok(项目路径,项目id)   ftok(const char *pathname,int proj_id);

            使用宏让操作系统随机分配:IPC_PRIVTE

                必须把获取到IPC对象标示符记录下来,告诉其他进程

        6.XSI可以创建的IPC对象:共享内存、消息队列、信号量

    四、共享内存

        1、由内核维护一块共享的内存区域,其他进程把自己的虚拟地址映射到这块内存,然后多个进程之间就可以共享这块内存

        2、这种进程间通信的好处是不需要信息复制,是进程间通信最快的一种方式。

        3、但这种通信方式会面临同步的问题。需要与其他的通信配合,最合适的就是信号。

        

        共享内存的编程模式:

            1.进程之间要约定一个健值

            进程A                                   进程B

            创建共享内存                      

            加载共享内存                     加载共享内存

            卸载共享内存                     卸载共享内存

            销毁共享内存    

            

        int shmget(key_t  key,size_t  size,int shmflg)

        功能:创建共享内存

        size:共享大小  尽量是4096的倍数   

        shmflg:IPC_CREAT|IPC_EXCL

        返回值:IPC对象标志符

        

        void *shmat(int shmid,const void * shmaddr,int shmflg)

        功能:加载共享内存(进程的虚拟地址与共享的内存映射)

        shmid:shmget的返回值

        shmaddr:进程提供的虚拟地址,如果为NULL,操作系统会自动选择  

        shmflg:

            SHM_RDONLY:限制内存的权限为只读

            SHM_REMAP:映射已经存的共享  

            SHM_RND:当shmaddr为空时自动分配

            SHMLBA:shmaddr的值不能为空

        返回值:映射后的虚拟地址

            

        int shmdt(const void* shmaddr);

        功能:卸载共享内存(进程的虚拟地址与共享的内存取消映射关系)

        

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

        功能:控制/销毁共享内存

        cmd:

            IPC_STAT:获取共享内粗的属性

            IPC_SET:设置共享内存的属性

            IPC_RMID:删除共享内存

            IPC_INFO:获取贡献内存的信息

          

          共享内存是进程见通信最快的一种,因此数据没有复制过程,但是无法得知进程之间的数据写入和读取,需要其他的通信方式的配额

    五、消息队列

        1.消息队列是一个由系统内核负责存储和管理、并通过IPC对象标示符获取的数据链表。

            int msgget(key_t key, int msgflg);

            功能:创建或获取消息队列

            msgflg:

                创建:IPC_CREAT|IPC_EXCL|0777

                获取:0

            返回:IPC对象标志符    

                

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

            功能:向消息队列发送消息

            msqid:msgget的返回值

            msgp:消息(消息类型加消息内容)的首地址

            msgsz:消息内容的长度

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

                功能:从消息队列接受消息

                msgp:存储消息的缓冲区

                msgsz:要接受的消息长度

                msgtyp:消息的类型,包含在消息的前4个字节。

                msgflg:

                    MSG_NOERROR:当消息的实际长度比msgsz还要长的话,

                        则按照msgsz长度截取再发送。否则产生错误。

                    MSG_NOWAIT:如果要接的消息不存在,直接返回

                        否则阻塞等待。

                    MSG_EXCEPT:从消息队列中接受第一个不

                    

            int msgctl(int msqid, int cmd, struct msqid_ds *buf);

            功能:控制/销毁消息队列

            cmd:

                IPC_STAT:获取消息队列的属性

                IPC_SET:设置消息队列的属性

                IPC_RMID:删除消息队列

    六、IPC相关命令:

         ipcs -m  察看共享内存

         ipcrm -m id 删除共享内存   

         

         ipcs -q  察看消息队列

         ipcrm -q  id  删除消息队列

           

    7、信号量

        信号量(信号灯),可以当作进程与进程之间共享的全局变量。一般用来为共享的资源计数。

        信号量的使用方式:

            1.进程A,创建信号量,并设置初始化(设置资源的数)     

            2.进程B,获取信号量,查询信号量(查询剩余资源的数量)。减少信号量(使用资源),增加信号量(资源使用完毕归还)

            3.当一个进程尝试减少信号量时,如果不能减(资源使用完毕),则进程可以进入等待状态。

                当信号量能够被减时,(其他进程把资源还回来了),进程会被唤醒。

        函数

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

             功能:创建信号量或获取信号量

             nsems:信号量的数量

             semflg:

                IPC_CREAT|IPC_EXCL|0644

              返回值:IPC对象标志符

                

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

               功能:对信号量增加或减少

               struct sembuf

               {

                    unsigned short sem_num; 信号的编号

                    short  sem_op;  对信号的处理

                    short  sem_flg;

                            如果信号量当前是0,函数立即返回。

                                IPC_NOWAIT:会阻塞

               }

          

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

                功能:对信号量控制或释放

                semnum:信号量的编号

                cmd:    

                    IPC_SET     设置信号量的属性

                    IPC_STAT    获取信号量的属性

                    IPC_RMID    删除信号量

                    IPC_INFO    获取信号量的信息

  • 相关阅读:
    hadoop用到的shell脚本
    hadoop搭建完全分布式集群
    hadoop搭建伪分布式集群
    ARM Compute Library编译安装
    OpenBlas交叉编译安装
    正则表达式去除所有标签html标签
    xstream实现xml字符串与对象直接的转换
    spring-boot中使用mybatis-plus代码生成器让你轻松的完成单表的CURD
    开源、免费软件和网站分享
    2020春软件工程助教工作期末总结
  • 原文地址:https://www.cnblogs.com/goul/p/9409435.html
Copyright © 2011-2022 走看看