我们知道的进程间通讯方式

一、信号量

   1.定义:用来进程同步的特殊变量,一个特殊计数器。

          大于0时,记录资源的数量,而且进程可以获取资源并利用;

          小于0时,记录等待资源的进程的数量,进程必须阻塞等待有其他进程释放资源。

          大于1时,称之为信号量计数器。

     信号量集:多个信号量的集合  ——>内核维护的一般是一个信号量集。

     内核对象:key 用户标识   ID 内核标识

 2.相关操作

  •    PV操作:

         P:信号量的值-1;获取临界资源时,如果当前资源不可用(信号量值为0), P在占据资源前会阻塞;

         V:信号量的值+1;释放占用的临界资源 ;

  •  创建获取信号量集合的内核对象

        如果是创建,必须对信号量初始化(设置初始值), 若是获取,不能对信号量初始化

           int semget((key_t)key,int semes,int flag);

            semes:创建信号量集时,执行创建的信号量集中信号量的个数;

            flag:指定操作方式:IPC_CREAT;     指定操作权限:文件权限的方式

            返回值:失败返回-1,成功返回信号量集内核标识ID。

  •  对信号量初始化

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

             semid:semget返回的文件描述符;

             semnum:下标;

             cmd:SETVAL;

union senum
{
        
    int val;
    
    struct semid_ds *buf;
      
    unsigned short *arry;

    struct seminfo *_buf;    
};
  •  访问临界P/V操作

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

  •    应用:

      A、B进程交替打印hello(A)、world(B).

      父子进程最快的一种IPC,一次交互过程相比于管道和消息队列,少两次数据的拷贝。

二、消息队列

    1.定义: 

        消息:   类型+数据  type:hello    消息都是独立的一条  type  world

        队列:一种先进先出的结构

   2.特点

  •  是消息存放的链表。具有特定的格式,存放在内存中,由消息队列标识符标识;
  • 消息队列允许一个或多个进程向他写入/读取消息;
  • 消息队列可实现消息的随机查询机制,不一定要以先进先出的顺序读取,也可按照类型进行读取;

   3.相关操作

  •   相关头文件: #include<sys/types.h>  #include<sys/ipc.h>  #include<sys/mag.h>
  •   查看系统上的消息队列:ipcs -q         删除系统上的消息队列:ipcm -q msgid
  •   创建: int msgget(key_t key,int msgflag);

         key:用户标识,用户程序使用相同的key值就能访问同一个内核对象;

         msgflag:指定是否创建内核对象,指定内核对象的访问权限(文件权限);

         返回值:如为内核标识/内核ID,进行下一步操作;如果为-1,则创建失败。  

  •   发送消息: int msgsnd(int msgid,void *msgp,size_t msgsz,int flag);

        *msgp为消息:类型 +数据; msgsz:数据的长度

struct mymseg{
  
  long mytype;   //消息:类型+数据
 
  char mtext[10];//数据的长度
};

 

  • 接收消息:int msgrcv(int msgid,void *ptr,size_t msgsz,int flag);
  • 删除消息队列:int msgctl(int msgid,int cmd,struct msqid_ds *buf) //这种删除立即生效

 *** 操作系统对进程间通用的信号量在内核中都是以信号量集管理的。也就是通过semget函数获取到的是信号量集的标识符。其他函数操作时,必须指明操作是哪个信号量集中的哪个信号量。类似数组的下标。

三、共享内存

   1.原理:多个进程共享一块物理内存地址,将物理内存地址分别映射在自己的虚拟空间上。10个进程将物理内存地址映射到自己的虚拟地址上,而且这10个进程可相互通信。由于是同一块内存地址,当第一个向这块内存写入数据时,其他进程也会看到。所以进程在使用这块空间时,必须做到同步控制

   2.相关操作

     int shmget((key_t)key,int semes,int flag);//size执行共享内存的空间大小,以字节为单位

  •  在本进程中分配虚拟地址映射到内核对象指向的共享空间上

      void *shmat(int semid,void *addr,int flahg);//默认情况下 addr为NULL,flag为0. 

     以上两步相当于malloc操作。

  •  将本进程中的指针与共享空间断开:

       int  shmdt(void *adrr);//free();

  •  销毁共享内存:

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

        说明:共享内存有一个计数器,如果调用shmat,计数器+1,调用shmat,计数器-1.shmat函数删除,仅仅删除该段的标识符,             而且不能通过shmat来连接该段。

四、管道 

        具体内容可参考博客:https://blog.csdn.net/rjp_1987/article/details/107514525

附加:

  内核(操作系统)  对象 (实体变量)  属性信息 系统调用函数访问对象;

  4G的虚拟空间地址   3G的用户空间是独立的 1G的内核空间是用户共享的;

  临界资源:同一时间段只能被一个进程访问的资源。

  临界区:访问临界资源的代码区域。

 原子操作:一旦开始就不能被打断的操作。

  同步:当调用函数时,阻塞等待条件发生,在访问临界资源时,多进程按照一定顺序执行。

  异步:当调用函数时,无论条件是否发生,函数会立刻返回,当条件发生后需要依赖系统的消息。通过通知机制,通知调用此             函数的进程。

 阻塞与非阻塞关注的是进程调用函数的状态。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值