进程间通信之共享内存(简单介绍消息队列和信号量)(2)

简介: 最快的进程间通信方式,共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据

comm.c

#include "comm.h"
static int commShm(int size, int flags)
{
  key_t key = ftok(PATHNAME, PROJ_ID);
  if (key < 0) {
    perror("ftok");
    return -1;
  }
  int shmid = 0;
  if ((shmid = shmget(_key, size, flags)) < 0) {
    perror("shmget");
    return -2;
  }
  return shmid;
}
int destroyShm(int shmid)
{
  if (shmctl(shmid, IPC_RMID, NULL) < 0) {
    perror("shmctl");
    return -1;
  }
  return 0;
}
int createShm(int size)
{
  return commShm(size, IPC_CREAT | IPC_EXCL | 0666);
}
int getShm(int size)
{
  return commShm(size, IPC_CREAT);
}


server.c

#include "comm.h"
int main()
{
  int shmid = createShm(4096);
  char* addr = shmat(shmid, NULL, 0);
  sleep(2);
  int i = 0;
  while (i++ < 26) {
    printf("client# %s\n", addr);
    sleep(1);
  }
  shmdt(addr);
  sleep(2);
  destroyShm(shmid);
  return 0;
}

client.c

#include "comm.h"
int main()
{
  int shmid = getShm(4096);
  sleep(1);
  char* addr = shmat(shmid, NULL, 0);
  sleep(2);
  int i = 0;
  while (i < 26) {
    addr[i] = 'A' + i;
    i++;
    addr[i] = 0;
    sleep(1);
  }
  shmdt(addr);
  sleep(2);
  return 0;
}

结果演示

image.png

注意:共享内存没有进行同步与互斥!


image.png

特性:


1.最快的进程间通信方式

2.生命周期随内核(并不会随着打开的进程退出而被释放)


注意事项:


共享内存的访问操作存在安全问题(竞争访问出现数据二义问题)


补充:


1.共享内存的本质就是开辟一块物理内存, 让多个进程映射同-块物理内存到自己的地址空间进行访问,实现数据共享的。

2.共享内存的操作是非进程安全的,多个进程同时对共享内存读写是有可能会造成数据的交叉写入或读取,造成数据混乱

3.共享内存的删除操作并非直接删除,而是拒绝后续映射,只有在当前映射链接数为0时,表示没有进程访问了,才会真正被删除

4.共享内存生命周期随内核,只要不删除,就一-直存在于内核中,除非重启系统(当然这里指的是非手动操作,可以手动删除)


消息队列


详细可以参考这篇博客,我这里是简单总结了一下消息队列

功能:实现进程间的数据传输

本质:内核中的一个优先级队列

实现:多个进程通过访问同一一个消息队列,以添加数据节点和获取数据节点实现通信

image.png

总结:


1、采用消息队列通信比采用管道通信具有更多的灵活性,通信的进程不但没有血缘上的要求,也不需要进行同步处理。

2、消息队列是一种先进先出的队列型数据结构;

3、消息队列将输出的信息进行了打包处理,可以保证以消息为单位进行接收;

4、消息队列对信息进行分类服务,根据消息的类别进行分别处理。

5、提供消息数据自动拆分功能,同时不能接受两次发送的消息。

6、消息队列提供了不完全随机读取的服务。 7、消息队列提供了完全异步的读写服务。


信号量


(这里做简单介绍)

作用:用于实现进程间的同步与互斥

本质:是一个计数器+ pcb等待队列


P操作:对计数器进行-1操作,判断计数是否大于等于0,正确则返回;失败则阻塞,其中阻塞就是把它置位可中断休眠状态,挂到pcb等待对联中,直到被唤醒

V操作:对计数器进行+ 1操作,若计数器小于等于0,则唤醒一个等待的进程

同步实现:

通过计数器对共享资源进行计数,在获取资源之前,则进行P操作,计数满足访问条件则访问,若不满足则阻塞当产生一个资源,则进行V操作,唤醒阻塞的进程

互斥实现:

初始化计数器为1,表示资源只有一一个。

访问资源之前进行P操作;访问资源完毕之后进行V操作


目录
相关文章
|
2月前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
261 2
|
3月前
|
存储 Linux 调度
深入理解操作系统:从进程管理到内存分配
【8月更文挑战第44天】本文将带你深入操作系统的核心,探索其背后的原理和机制。我们将从进程管理开始,理解如何创建、调度和管理进程。然后,我们将探讨内存分配,了解操作系统如何管理计算机的内存资源。最后,我们将通过一些代码示例,展示这些概念是如何在实际操作系统中实现的。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
|
13天前
|
C语言 开发者 内存技术
探索操作系统核心:从进程管理到内存分配
本文将深入探讨操作系统的两大核心功能——进程管理和内存分配。通过直观的代码示例,我们将了解如何在操作系统中实现这些基本功能,以及它们如何影响系统性能和稳定性。文章旨在为读者提供一个清晰的操作系统内部工作机制视角,同时强调理解和掌握这些概念对于任何软件开发人员的重要性。
|
13天前
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
|
22天前
|
算法 调度 开发者
深入理解操作系统:从进程管理到内存分配
本文旨在为读者提供一个深入浅出的操作系统知识之旅,从进程管理的基础概念出发,探索内存分配的策略与技巧。我们将通过实际代码示例,揭示操作系统背后的逻辑与奥秘,帮助读者构建起对操作系统工作原理的直观理解。文章不仅涵盖理论知识,还提供实践操作的指导,使读者能够将抽象的概念转化为具体的技能。无论你是初学者还是有一定基础的开发者,都能在这篇文章中找到有价值的信息和启发。
|
26天前
|
算法 调度 C++
深入理解操作系统:从进程管理到内存分配
【10月更文挑战第42天】本文将带你进入操作系统的神秘世界,探索其核心概念和关键技术。我们将从进程管理开始,了解操作系统如何协调和管理多个程序的运行;然后,我们将深入研究内存分配,看看操作系统如何有效地分配和管理计算机的内存资源。通过这篇文章,你将获得对操作系统工作原理的深入理解,并学会如何编写高效的代码来利用这些原理。
|
27天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
2月前
|
缓存 算法 调度
深入浅出操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅。我们将从进程管理的基本概念出发,逐步深入到内存管理的复杂世界,最终探索如何通过实践技巧来优化系统性能。文章将结合理论与实践,通过代码示例,帮助读者更好地理解操作系统的核心机制及其在日常技术工作中的重要性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往操作系统深层次理解的大门。
|
2月前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第5天】麒麟系统mate-indicators进程占用内存过高问题解决
178 0
|
3月前
|
消息中间件
共享内存和信号量的配合机制
【9月更文挑战第16天】本文介绍了进程间通过共享内存通信的机制及其同步保护方法。共享内存可让多个进程像访问本地内存一样进行数据交换,但需解决并发读写问题,通常借助信号量实现同步。文章详细描述了共享内存的创建、映射、解除映射等操作,并展示了如何利用信号量保护共享数据,确保其正确访问。此外,还提供了具体代码示例与步骤说明。