单片机学习小组
直播中

恐龙之家

8年用户 731经验值
私信 关注

linux中的共享内存是指什么?共享内存有哪些优缺点

什么是进程?进程有哪几种状态?
共享内存是指什么?共享内存有哪些优缺点?

回帖(1)

郭霞

2022-2-28 15:13:54
1.进程
  fork():创建进程,若返回子进程的pid,说明正在运行的是父进程; 返回0,说明正在运行的是子进程.
  exec():将当前进程覆盖掉,可以通过调用fork()复制启动一个子进程,并且在子进程中调用 exec系列函数替换子进程,把fork()和exec系列函数结合在一起使用就是创建一个新进程所需要的一切了。
  exit(),_exit():终止进程。_exit()直接通过系统调用中止,而exit()还会检查缓冲区,将文件缓冲区的内容写回文件。
  wait():暂停父进程的执行,直到有信号来到或子进程结束。返回子进程结束的状态信息。
  waitpid():指定等待某个pid的子进程。
进程的状态:
  ①运行态(正在运行)
  ②就绪态(在等待队列中排队)
  ③可中断睡眠态(等待某些事件、信号或者资源而进入)
  ④不可中断睡眠态(等待输入或输出完成I/O)
  ⑤暂停态
  ⑥退出态(正常退出——exit();异常退出(变成了僵尸态)——kill() )
2.信号
  信号用于通知进程发生了异步事件。
  linux有62种信号。分为实时信号(信号值为1–31,支持排队,发送多少信号给进程,进程就处理多少次)和非实时信号(信号值为34–64,不支持排队)。
  信号的生成有三类:
  ①程序错误:如零作除数;
  ②外部事件:如用户在终端按下某个按键
  ③显示请求:如使用kill()向某一程发送信号
  信号的处理:
  ①忽略信号
  ②捕获信号:由信号处理函数处理
  ③执行默认动作:系统为每种信号规定了一个默认动作
  signal():捕获信号。进程接收到信号后会跳转到响应函数执行。
  kill():发送信号给自身的进程或其它进程
  raise():只能向自身进程发送信号
  alarm():经过seconds时间后,向当前进程发送sigalarm信号

3.管道  
  管道可以传输数据。管道通常把一个进程的输出连接到另一个进程的输入。
  管道分为命名管道(有名)和匿名(无名)管道。
  匿名管道只能用于父子进程之间的通信。对匿名管道的读写可以使用read()和write()函数。
  pipe(int pipefd[2]):创建一个匿名管道,数组pipefd用于返回引用管道末端的文件描述符,分别指向管道的读取端和写端。
  父子进程通过管道通信的操作为:
  ①父进程通过pipe()创建匿名管道
  ②父进程调用fork()启动子进程
  ③分别关闭父进程和子进程的一个写入或读取端
  命名管道可以在不相关进程之间传递数据,以文件形式存在文件系统中,可以使用open()获取文件描述符,遵循先进先出的原则。
  mkfifo():创建命名管道。一个进程向FIFO文件写数据,而另一个进程在FIFO文件中读取数据。
4.消息队列  
  消息队列提供了从一个进程向另一个进程发送数据块的方法。
  消息队列、共享内存、信号量统称为IPC对象。这些对象使用key唯一标识,它们被创建后不会因为进程的退出而消失。
  消息队列标识符:meqid,共享内存标识符:shmid,信号量标识符:semid
  消息队列和信号的区别:信号承载的信息少,消息队列可以承载大量的数据。
  消息队列和管道的区别:消息队列可以有选择地接收数据,如可以按消息类型接收。
  msgget():创建或打开消息队列,返回消息队列标识符。
  msgsend():向消息队列发送信息,当消息队列满时将会阻塞。
  msgrcv():从消息队列种读取消息并。
  msgctl():设置或获取消息队列的相关属性。
5.IPC信号量  
  信号量本质是一个计数器,用于协调多进程间对共享对象的读取,保护共享资源。
  信号量只能进行P和V操作。P操作是占用临界资源;V操作是释放临界资源。
  P操作:如果有可用的资源(信号量值大于0),则占用一个资源(给信号量值减去一,进入临界区代码 ;如果没有可用的资源(信号量值等于 0),则处于阻塞状态,直到系统将资源分配给该进程(进入等待队列,一直等到资源轮到该进程)。
  V操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞的进程。如果没有进程等待它,则释放一个资源(给信号量值加一)。
  semget():创建或获取一个已经创建的信号量,成功创建则返回信号量标识符。
  semop():进行P和V操作。
  semctl():对信号量进行控制操作,如设置信号量的初始值。
6.共享内存  
  共享内存是效率最高的IPC通信机制(消息队列、信号量、共享内存),可以在多个进程之间共享和传递数据,进程间需要共享的数据被放在共享内存区域,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去,因此所有进程都可以访问共享内存中的地址。
  共享内存是属于临界资源,在某一时刻最多只能有一个进程对其操作(读/写数据),共享内存一般不能单独使用,而要配合信号量、互斥锁等协调机制。
  共享内存的思想:进程与进程之间虚拟内存空间本来相互独立,不能互相访问的,但是可以通过某些方式,使得相同的一块物理内存多次映射到不同的进程虚拟空间之中,这样的效果就相当于多个进程的虚拟内存空间部分重叠在一起。
  共享内存的优缺点:①优点:进程间数据不用传送,直接访问内存,加快了程序效率。 ②缺点:没有提供同步的机制,这使得我们在使用共享内存进行进程间通信时,往往要借助其他的手段(如信号量、互斥量等)来进行进程间的同步工作。
  shmget():创建或获取一个共享内存对象,返回共享内存标识符。
  shmat():把共享内存区对象映射到进程的地址空间。
  shmdt():解除进程与共享内存之间的映射
  shmctl():获取或者设置共享内存的相关属性,如删除共享内存。
7. 线程  
  进程是资源管理的最小单位,线程是程序执行的最小单位.
  进程在进行切换时都需要有比较复杂的上下文切换等动作,因为要保存当前进程上下文的内容,还要恢复另一个进程的上下文,如果是经常切换进程的话,这样子的开销就过大。为了进一步减少CPU在进程切换时的额外开销, 需要使用线程。
  在进程中创建一个新线程时,新的执行线程将拥有自己的栈,但与它的创建者共享全局变量、文件描述符、信号处理函数和当前目录状态。
  pthread_create() :创建一个线程,通过函数指针,跳转到要执行的函数处
  pthread_attr_init():初始化线程对象属性
  pthread_attr_destroy() 销毁线程属性对象
  pthread_join():设置线程为可结合状态
  pthread_detach():设置线程为分离状态
  pthread_exit():线程退出
  线程的分离和可结合状态:
  一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。如果某个线程想要等待另一个线程退出,并且获取它的退出值,那么就可以使用pthread_join()函数完成,以阻塞的方式等待指定的线程结束。
  线程的调度策略:
  ①分时调度:根据优先级调度
  ②实时调度——先进先出
  ③实时调度——时间片轮转方式
8.POSIX信号量  
  实现进程间同步或临界资源的互斥访问。
  分为无名信号量和有名信号量。无名信号量则直接保存在内存中, 而有名信号量则要求创建一个文件。
  无名信号量只能应用在同一进程内的线程之间同步或者互斥。相反,有名信号量可以通过名字访问, 因此可以被任何知道它们名字的进程或者进程/线程使用.
  对信号量的操作分为P操作和V操作。如果有可用的资源(信号量值大于0),则占用一个资源(给信号量值减去一,进入临界区代码);如果没有可用的资源(信号量值等于0),则被阻塞到,直到系统将资源分配给该进程/线程。
9.互斥锁  
  互斥锁的状态只有两种,开锁或闭锁。当互斥锁被线程持有时,该互斥锁处于闭锁状态,线程获得互斥锁的所有权,线程能够访问共享资源。当该线程释放互斥锁时,该互斥锁处于开锁状态,线程失去该互斥锁的所有权。
  pthread_mutex_init():互斥锁初始化,成功初始化返回0
  pthread_mutex_lock():获取互斥锁(阻塞方式)
  pthread_mutex_destroy():销毁互斥锁。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分