Chinaunix首页 | 论坛 | 博客
  • 博客访问: 693333
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2020年(1)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: LINUX

2016-10-22 23:57:55

内核资料收集

1. 概述
        IPC是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行下列操作的一组进程机制:
            a. 通过信号量与其它进程进行同步
            b. 向其它进程发送消息或者从其它进程接收消息
            c. 和其它进程共享一段内存区
        IPC数据结构是在进程请求IPC资源(信号量/消息队列/或共享内存区)时动态创建的. 每个IPC资源都是持久的: 除非被进程显示地
    释放,否则永远驻留
        在内存中(直到系统关闭). IPC资源可以由任一进程使用,包括那些不共享祖先进程创建的资源的进程.
        由于一个进程可能需要同类型的多个IPC资源,因此每个新资源都是使用一个32位的IPC关键字来标识的,这和系统的目录树中的文件
    路径名类似. 每个IPC资源都有一个32位的IPC标识符, 这与和打开文件相关的文件描述符有些类似. IPC标识符由内核分配给IPC
    资源, 在系统内部是唯一的,而IPC关键字可以由程序员自由地选择.
        当两个或者更多的进程要通过一个IPC资源进程通信时, 这些进程都要引用该资源的IPC标识符.

2. 使用IPC资源
        IPC资源创建: 调用semget()/msgget()/shmget()函数分别用于创建信号量/消息队列/共享内存. 这三个函数主要目的都是从IPC关键
    字(作为第一个参数传递)中导出相应的IPC标识符,进程以后就可以使用这个标识符对资源进程访问. 如果还没有IPC资源和IPC关键字
    相关联, 就创建一个新的资源. 如果一切都顺利,那么函数就返回一个正的IPC标识符; 否则,就返回一个错误码:
          
        两个独立的进程想共享一个公共的IPC资源. 这可以使用两种方法来达到:
            a. 这两个进程统一使用固定的, 预定义的IPC关键字. 这是最简单的情况,对于由很多进程实现的任一复杂应用程序也工作得很
                好. 然而,另外一个无关的程序也可能使用了相同的IPC关键字.在这种情况下, IPC函数可能被成功地调用,但返回错误资源
                的IPC标识符
            b. 一个进程通过指定IPC_PRIVATE作为自己的IPC关键字来调用semget()/msgget()/shmget()函数. 一个新的IPC资源因此而被
                分配,这个进程或者可以与应用程序中的另一个进程共享自己的IPC标识符,或者自己创建另一个进程. 这种方法确保IPC资源
                不会偶然被其他应用程序使用.
        semget()/msgget()/shmget()函数的最后一个参数可以包括三个标志. IPC_CREAT说明如果IPC资源不存在,就必须创建它;
 IPC_EXCL说明如果资源已经存在而且设置了IPC_CREAT标志,那么函数就必定失败; IPC_NOWAIT说明访问IPC资源时进程从不阻
    塞(典型情况如取得消息或获取信号量).
        即使进程使用了IPC_CREAT和IPC_EXCL标志,也没有办法保证对一个IPC资源进行排它访问,因为其它进程也可能用自己的IPC标识
    符引用这个资源.
        为了把不正确地引用资源的风险降到最小, 内核不会在IPC标识符一空闲时就再利用它. 相反分配给资源的IPC标识符总是大于给
    同类型的前一个资源所分配的标识符(唯一的例外发生在32位的IPC标识符溢出时). 每个IPC标识符都是通过结合使用与资源类型相关
    的位置使用序号(slot usage sequence number), 已分配资源的任意位置索引(slot index)以及内核中为可分配资源所选定的最大值计算
    出来的.如果我们使用s来表示位置使用序号, M来代表可分配资源的最大数目, i代表位置索引, 此处0<=i         ...
            ipc_id_ary数据结构有两字段: p和size. p字段是一个指向kern_ipc_perm数据结构的指针数组, 每个结构对应一个可分配资源.
    size字段是这个数组的大小.最初数组为共享内存区/消息队列与信号量分别存放1,16,128个指针. 当太小时,内核动态地增大数组. 但是
    每种资源都有个上限. 系统管理员可以修改/proc/sys/kernel/sem, /proc/sys/kernel/msgmni, /proc/sys/kernel/shmmni这三个文件以
    改变这些上限.
          
            每个kern_ipc_perm数据结构与一个IPC资源相关,并且包含下表所示的字段. uid/gid/cuid/cgid分别存放资源的创建者的用户标识
    和数组标识符以及当前资源属主/组以及其它用户的读写访问权限. 
            semctl()/msgctl()/shmctl()都可以用来处理IPC资源. IPC_SET子命令允许进程改变属主的用户标识符和组标识符以及ipc_perm
    数据结构中的许可权位掩码. IPC_STAT和IPC_INFO子命令取得和资源有关的信息. 最后IPC_RMID子命令释放IPC资源.
            IPC资源创建后, 进程就可以通过一些专用函数对这个资源进程操作. 进程可以执行semop()函数获得或释放一个IPC信号量.
 当进程希望发送或接收一个IPC消息时,就分别使用msgsnd()/msgrcv()函数. 最后,进程可以分别使用shmat()和shmdt()函数把一个共享
    内存区附加到自己的地址空间中或者取消这种附加关系.
3. ipc系统调用
            ipc函数都必须通过适当的linux系统调用实现. 在80x86体系结构中, 只有一个名为ipc()的系统调用. 当进程调用一个IPC函数
    时, 如msgget()该函数实际上调用C库中的一个封装函数,该函数又通过传递msgget()的所有参数加上一个子命令码(本例中是
    MSGGET)来调用ipc()系统调用. sys_ipc()服务例程检查子命令代码,并调用内核函数实现所请求的服务.
阅读(868) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~