天天看点

一起talk C栗子吧(第九十四回:C语言实例--SystemV IPC结构概述)

各位看官们,大家好,上一回中咱们说的是进程间通信之临界资源的例子,这一回咱们说的例子是:SystemV IPC结构概述。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们, 我们通常所说的IPC是进程间通信的简称,这只是一个抽象的称呼,今天说的SystemV IPC是具体的一种IPC,因为它广泛应用于Unix SystemV版本中,所以取名叫作SystemV IPC。当然了,我们使用的Linux系统中也支持该类型的IPC。接下来我们详细介绍SystemV IPC。

1.SystemV IPC的定义

SystemV IPC是在系统内核中实现的,它是内核中的一种结构,该结构是一种抽象的概念,我们可以把它实现为具体的对象。比如,电脑是一个抽象的概念,而台式电脑,笔记本电脑和平板电脑就是具体的一种电脑产品。与SystemV IPC结构有关的SystemV IPC对象有:共享内存,消息队列和信号量,我们会在后面章回中介绍这些具体的SystemV IPC对象。

2.SystemV IPC的使用

在内核中需要使用标识符来使用IPC结构,标识符类似于我们使用文件时的文件描述符,它是一个非负整数值,不过它的值通常都是比较大的数值。标识符是内核里的东西。我们通常没有办法直接使用,因此需要使用键(key)来与标识符建立联系,这样我们就可以通过操作键来操作SystemV IPC在内核中的结构,进而操作SystemV IPC对象,比如共享内存。

在程序中我们可以任意指定一个整数值来在当键值,不过该方法不太好。常用的是使用IPC_PRIVATE键来创建IPC对象。或者使用ftok函数来生成唯一的键。

3.SystemV IPC的结构

SystemV IPC结构有一个ipc_perm结构,该结构是一个结构体,它包含有IPC的权限和所有者等信息,具体的内容如下(来自:/linux-4.0.3/include/linux/ipc.h文件中)

/* used by in-kernel data structures */
struct kern_ipc_perm
{
    spinlock_t  lock;
    bool        deleted;
    int     id;
    key_t       key;
    kuid_t      uid;  //must
    kgid_t      gid;  //must
    kuid_t      cuid; //must
    kgid_t      cgid; //must
    umode_t     mode; //must
    unsigned long   seq;
    void        *security;
};
           

该结构中不同的SystemV IPC对象会有不同的定义,但是我添加了//must的成员是每个SystemV IPC对象必须包含的。

4.SystemV IPC的使用

SystemV IPC的使用随着SystemV IPC对象的不同而不同,但是整体的使用流程还是一致的:

  • 获取一个SystemV IPC对象;
  • 操作SystemV IPC对象;
  • 释放SystemV IPC对象。

我们在后面章回中介绍到具体的SystemV IPC对象时会介绍详细的操作方法。

此外,Linux系统中的SystemV IPC对象是在内核中的,不像文件一样可以被查看到。强大的Linux提供了相关的命令来操作SystemV IPC。

ipcs命令可以查看系统中所有的SystemV IPC对象,它们是:共享内存,消息队列和信号量。

下面是在系统中运行ipcs的结果:

ipcs              //运行ipcs命令

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
      talk8                             dest         
     talk8                               dest         
...               //其它的省略
------ Semaphore Arrays --------
key        semid      owner      perms      nsems     
           talk8                         
   //这里显示为空,表示没有共享内存这个IPC对象
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
  //这里显示为空,表示没有消息队列这个IPC对象
           

另外,可以使用ipcs -m/q/s 单独查看系统中的共享内存,消息队列和信号量这些IPC对象,这里就不举例子了,大家可以自己动手试试。

ipcrm命令可以用来删除系统中具体的IPC对象

ipcrm -m/q/s id 可以用来删除:共享内存,消息队列和信号量这些IPC对象。命令中的id可以通过运行ipcs来查看,比如, 我们在上面例子中shmid那一列的内容就是共享内存的id。

此外,我们在Linux系统中可以通过查看特殊目录下的文件来得到ipc的信息:

共享内存的信息位于 /proc/sysvipc/shm 文件中
消息队列的信息位于 /proc/sysvipc/msg 文件中
信号量的信息位于  /proc/sysvipc/sem  文件中
           

我们可以使用cat命令来查看ipc对象的信息,下面是查看系统中信号量的例子:

cat /proc/sysvipc/sem   //执行cat命令
key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime
-                                 
           

各位看官,关于SystemV IPC结构概述的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。

继续阅读