0
点赞
收藏
分享

微信扫一扫

Linux内核篇之SYSTEM-V

一点读书 2022-05-03 阅读 66

Linux内核篇之SYSTEM-V

1.消息队列

system-v ipc特点:

  • 独立于进程
  • 没有文件名和文件描述符
  • IPC对象具有Key和ID

消息队列用法:

  • 定义一个唯一Key (ftok)
  • 构造消息对象(msgget)
  • 发送特定类型的消息(msgsnd)
  • 接受特定类型的消息(msgrcv)
  • 删除消息队列(msgct)

相关函数:

  • ftok

    • 功能 :获取一个Key
    • 函数原型:ket_t ftok(const char *path,int proj_id)
      • 参数:
        • path:一个合法路径
        • proj_id:一个整数
      • 返回值:
        • 成功:合法Key
        • 失败:-1
  • msgget

    • 功能:获取消息队列ID
    • 函数原型:int msgget(key_t key,int msgflg)
    • 参数:
      • key:消息队列key
      • msgflg:
        • IPC_CREAT:如果消息队列不存在则创建一个
        • mode:访问权限
        • 权限只有读和写,执行权限是无效的,例如 0777 跟 0666 是等价的。
          当 key 被指定为 IPC_PRIVATE 时,系统会自动产生一个未用的 key 来对应一个新的消
          息队列对象,这个消息队列一般用于进程内部间的通信。
    • 返回值:
      • 成功:返回消息队列ID
      • 失败:-1
  • msgsnd

    • 功能:发送消息到消息队列

    • 函数原型:int msgsnd(int msqid,const void*msgp,size_t msgsz,int msgflg)

    • 参数:

      • msqid:消息队列ID

      • msgp:消息缓存区

        • struct msgbuf

          {

          ​ long mtype;//消息标识

          ​ char mtext[1];//消息内容

          }

      • msgsz:消息正文的字节数

      • msgflg:

        • ipc_nowait:非阻塞发送
        • 0:阻塞发送
      • 返回值:

        • 成功:0
        • 失败:-1
  • msgrcv:

    • 功能:从消息对接读取消息

    • 返回值:

      • 成功:0
      • 失败:-1
    • 函数原型:ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);

    • 参数:

      • msqid:消息队列lD

      • msgp:消息缓存区

      • nsgsz:消息正文的字节数

      • msgtyp:要接受消息的标识

      • msgflg:

        • IPC_NOWAIT:非阻塞读取
        • MSG NOERROR:载断消息
        • 0:阻塞读取
  • msgctl:

    • 功能:设置获取消息队列的相关属性
    • 函数原型:int msgctl(int msgqid,int cmd,struct maqid_ds *buf)
    • 参数:
      • msgqid:消息队列id
      • cmd:
        • IPC_STAT:获取消息队列的属性
        • IPC_SET:设置消息队列的属性
        • IPC_RMID:删除消息队列
      • buf:相关结构体缓冲区

2.信号量

本质:计数器

作用:保护共享资源

  • 互斥 :在一个时刻只有一个进程可以访问
  • 同步 :在互斥访问的基础上加上顺序

1.临界资源
临界资源是一次仅允许一个进程使用的共享资源。各进程采取互斥的方式,实现共享的资源称作临界资源。属于临界资源的硬件有,打印机,磁带机等;软件有消息队列,变量,数组,缓冲区等。诸进程间采取互斥方式,实现对这种资源的共享。

2.临界区:
每个进程中访问临界资源的那段代码称为临界区(criticalsection),每次只允许一个进程进入临界区,进入后,不允许其他进程进入。不论是硬件临界资源还是软件临界资源,多个进程必须互斥的对它进行访问。多个进程涉及到同一个临界资源的的临界区称为相关临界区。使用临界区时,一般不允许其运行时间过长,只要运行在临界区的线程还没有离开,其他所有进入此临界区的线程都会被挂起而进入等待状态,并在一定程度上影响程序的运行性能。

信号量工作原理:

  • 由于信号量只能进行两种操作:等待和发送信号,即 P 操作和 V 操作,锁行为就是 P 操作,解锁就是 V 操作,可以直接理解为 P 操作是申请资源, V 操作是释放资源。 PV 操作是计算机操作
  • 系统需要提供的基本功能之一,它们的行为是这样的:
    • P 操作:如果有可用的资源(信号量值大于 0),则占用一个资源(给信号量值减去一,进
      入临界区代码) ; 如果没有可用的资源(信号量值等于 0),则阻塞,直到系统将资源分配
      给该进程(进入等待队列,一直等到资源轮到该进程)。这就像你要把车开进停车场之前,
      先要向保安申请一张停车卡一样, P 操作就是申请资源,如果申请成功,资源数(空闲的停
      车位)将会减少一个,如果申请失败,要不在门口等,要不就走人。
    • V 操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞的进程。如果
      没有进程等待它,则释放一个资源(给信号量值加一),就跟你从停车场出去的时候一样,
      空闲的停车位就会增加一个

信号量的用法:

  • 定义一个唯一key(ftok)
  • 构造一个信号量(semget)
  • 初始化信号量(semctl SETVA)
  • 信号量进行P/V操作(semop)
  • 删除信号集(semctl RMID)

semget函数:

  • 功能:获取信号量 ID
  • 函数原型:int semget(key_t key ,int nsems, int semflg)
  • 参数:
    • key: 信号量键值
    • nsems:信号量数值
    • semflg:
      • IPC_CREAT:信号量不存则创建
      • mode:权限
    • 返回值:
      • 成功:信号量ID
      • 失败:-1

semctl函数:

  • 功能:获取或设置信号量的相关属性操作

  • 函数原型:int semctl(int semid,int semnum,int cmd,union semun arg)

  • 参数:

    • semid:信号量的ID

    • semnum:信号量的编号

    • cmd:

      • IPC_STAT:获取信号量的属性信息
      • IPC_SET:设置信号量的属性
      • IPC_RMID:删除信号量
      • IPC_SETVAL:设置信号量的值
    • arg:

      union semun
      {
      
      	int val;
      	struct semid_ds *buf;
      
      }
      
      • 返回值:
        • 成功:由CMD类型决定
        • 失败:-1

semop函数:

  • 功能:对信号量进行加减操作

  • 函数原型:int semop(int semid,struct sembuf *sops,size_t nsops)

  • 参数:

    • semid: 信号量ID

    • sops:信号量操作结构体数组

      struct sembuf
      {
      
      	short sem_num;//信号量编号
      	short sem_op;//信号量P/V操作
      	short sem_flg;//信号量行为  SEM_UNDO
      
      }
      
    • nsops:信号量数量

    • 返回值:

      • 成功:0

      • 失败:-1

举报

相关推荐

0 条评论