【Linux】进程间通信

进程间通信的五种方式

1.有名管道

有名管道可以在任意两个进程间通信

有名管道的创建:
(1)命令创建:mkfifo FIFO

​ (2)系统调用创建:

filename是管道名,mode是文件权限
int mkfifo(const char *ilename,mode_t mode);

2.无名管道

无名管道主要应用于父子进程间的通信

无名管道的创建:

int pipe(int fds[2]);
/*
   成功返回0,失败返回-1
  fds[0]是管道读端的描述符
  fds[1]是管道写端的描述符
*/

{
  int fds[2];
  int res=pipe(fds);
  ...
  char buff[127]={0};
  read(fds[0],buff,127);//读
  write(fds[1],buff,127);//写
}

管道的特点
◼ 无论有名还是无名,写入管道的数据都在内存中
◼ 管道是一种半双工通信方式
◼ 有名和无名管道的区别:有名可以在任意进程间使用,而无名主要在父子进程间

3.信号量

信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V操作信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二元信号量。如果信号量的值大于 1,则称之为计数信号量。

操作信号量的接口介绍:

 /*
  semget()创建或者获取已存在的信号量
  semget()成功返回信号量的 ID, 失败返回-1
  key:两个进程使用相同的 key 值,就可以使用同一个信号量
  nsems:内核维护的是一个信号量集,在新建信号量时,其指定信号量  集中信号量的个数
 semflg 可选: IPC_CREAT IPC_EXCL
 */
 int semget(key_t key, int nsems, int semflg);

 /*
  semop()对信号量进行改变,做 P 操作或者 V 操作
  semop()成功返回 0,失败返回-1
  struct sembuf
 {
  unsigned short sem_num; //指定信号量集中的信号量下标
  short sem_op; //其值为-1,代表 P 操作,其值为 1,代表 V 操作
  short sem_flg; //SEM_UNDO
 };
  */
 int semop( int semid, struct sembuf *sops, unsigned nsops);

 /*
 semctl()控制信号量
 semctl()成功返回 0,失败返回-1
 cmd 选项: SETVAL IPC_RMID
 union semun
 {
  int val;
  struct semid_ds *buf;
  unsigned short *array;
  struct seminfo *_buf;
 };
 */
  int semctl( int semid, int semnum, int cmd, ...);

4.消息队列

消息队列是消息的链接表,存放在内核中,一个消息队列由一个标识符(消息ID)来标识。

特点:1.消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级

​ 2.消息队列独立于发送与接收进程,进程终止时,消息队列及其内容不会被删除

​ 3.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按照消息的类型读取

消息队列接口介绍

```C
/*
   用于创建或者获取一个消息队列
   成功返回消息队列ID,失败返回-1
   msqflg: IPC_CREAT
*/
 int msgget(key_t key, int msqflg);

 /*
  msgsnd()发送一条消息,消息结构为:
  struct msgbuf
  {
    long mtype; // 消息类型, 必须大于 0
    char mtext[1]; // 消息数据
 };
  成功返回 0, 失败返回-1
  msqsz: 指定 mtext 中有效数据的长度
  msqflg:一般设置为 0 可以设置 IPC_NOWAIT
*/
  int msgsnd( int msqid, const void *msqp, size_t msqsz, int msqflg);

 /*
   msgrcv()接收一条消息
   msgrcv()成功返回 mtext 中接收到的数据长度, 失败返回-1
   msqtyp: 指定接收的消息类型,类型可以为 0
   msqflg: 一般设置为 0 可以设置 IPC_NOWAIT
 */
   ssize_t msgrcv( int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg);

 /*
   msgctl()控制消息队列
   msgctl()成功返回 0,失败返回-1
   cmd: IPC_RMID
 */
  int msgctl( int msqid, int cmd, struct msqid_ds *buf);

5.共享内存

共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。

共享内存的接口介绍:

/*
    用于创建或获取已存在的共享内存;
    成功返回共享内存的ID,失败返回-1;
    key:不同的进程使用相同的key值可以获取到同一个共享内存
    size:创建共享内存时,指定要申请的共享内存的空间大小
    shmflg:IPC_CREAT   IPC_EXEC
*/
int shmget(key_t ket,size_t size,int shmflg);

/*
  将申请的共享内存的物理内存映射到当前进程的虚拟地址空间上
  成功返回共享内存的首地址,失败返回NULL
  shmid:共享内存的ID
  shmaddr:一般给 NULL,由系统自动选择映射的虚拟地址空间
  shmflg: 一般给 0, 可以给 SHM_RDONLY 为只读模式,其他的为读写
*/
void *shmat(int shmid,const void *shmaddr,int shmflg);

/*
  断开当前进程的shmaddr指向的共享内存映射
  成功返回0,失败返回-1
*/
int shmdt(const void *shmaddr);

/*
  用于控制共享内存
  成功返回0,失败返回-1
  cmd:IPC_RMID
*/
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Serendipity---小ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值