面试笔记(一):系统编程(Linux下进程虚拟空间布局、进程间的通信以及应用场景)

1.Linux下进程虚拟空间布局


在Linux中,每一个进程都抽象成一个task_struct结构体,称为进程描述符,存储着各方面的信息,如:打开的文件、信号、内存等。task_struct中的一个属性mm_struct管理着进程的所有虚拟内存,称为内存描述符。

在mm_struct结构体中,存储着进程各个内存段的开始以及结尾,如上图所示。这进程使用的物理内存,即常驻内存RSS页数,这个内存使用的虚拟地址空间VSZ页数,还有这个进程虚拟内存区域集合和页表。

如图所示,进程有text segment(代码段), data segment(数据段), BSS segment, heap, memory mapping segment(内存映射段), stack(栈)。

BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区

详细介绍:http://wangxuemin.github.io/2015/07/30/LINUX程序(进程)在内存中的布局/


2.进程间的通信以及应用场景(转自:https://www.zybuluo.com/wangjialin/note/698812)

通信的目的:数据传输、共享数据、资源共享、通知事、进程控制

信号(signal)通信机制

  1. 特点:只能发送单个信号而不能传送数据
  2. 信号机制是UNIX为处理进程中断设计的,通过发送指定信号来通知进程某个异步事件的发生,以迫使进程执行信号处理程序。换言之,这个通信机制就相当于只能由一方发出某个命令让另一方按照约定去做相应的操作,至于另一方做了没做怎么做发出方并不关心。信号本质是一组预定义的值(比如SIGIN是与终端交互相关的信号,代表键盘中断等等),是一种“软中断”,
  3. 应用场景:进程执行非法指令或段违例,发生浮点错,某些按键(ctrl+c)


管道(pipeline)通信机制

  1. 特点:官道实质是一个连接读写进程的共享文件,但是是单向的
  2. 管道分为有名管道和无名管道。 
    • 无名管道实际上是内存的一个临时存储区,由系统安全控制并独立于创建他的进程的内存区。读写进程就是通过这个存储区来进行数据交流的。管道对于数据采取先进后出的方式管理,只能读一次不能搜索,两个进程必须拥有共同的祖先,具体是通过管道的inode节点的特征位互斥标志实现读写不能同时发生;其次,必须确定两方都存在的时候才能进行读写操作;管道大小有限,需要传输的数据太大的时候需要进行切分,否则会引起管道溢出而阻塞write,反之,管道内是空的时候读进程会出现read阻塞直到被唤醒。
    • 有名管道解决了无名管道只能连接两个具有共同祖先的进程的问题,有名管道类似于一般文件,具有文件名,进程就像调用一般文件一样进行系统调用open打开管道并通过read和write来读写管道内数据
  3. 应用场景:无名管道——操作系统内需要进程间有较大数据量通信的的地方;有名管道——服务器通过网络与多个用户进行交互


消息传递(message passing)通信机制

  1. 特点:消息传递机制不仅使进程可以通信并且提供了同步的能力,对于开发者而言,编写程序比较简单,方便易用;
  2. 进程间通过一个共享的数据结构——信箱来进行异步通信,每一个信箱都有唯一标识符,简介通信使得发送进程和接受进程不再非得是一对一的关系,还可以一对多。发送进程发送消息的时候,通过send(A,消息),如果信箱A没有满,信件就送到信箱A指针所指的位置并释放接受者,否则发送者切换到等待状态;接受进程接收消息时,通过receive(A,消息),如果信箱非空,就取出消息并释放等待信箱的发送者,若信箱为空,就切换为等待状态
  3. 应用场景:B.Hansen的消息缓冲机制,客户机和服务器交互

共享主存(shared memory)通信机制

  1. 特点: 类似管道,在主存中开辟一个公共存储区,最大的特点是可由多个独立进程共享效率比较高,常常和其他通信机制比如信号配合使用无需复制,快捷,信息量大
  2. 要通信的进程将自己的虚地址空间映射到共享主存区,发送进程将信息写入共享主存后接受进程可以从此位置读取信息。需要注意的是共享主存的页面在么一个共享进程的页表中都有页表项引用,但是不是所有进程的虚存段都有相同的地址,因为不止一个进程可将共享主存映射到自己的虚地址空间去
  3. 应用场景:需要多个进程使用并维护一个资源的情况

信号灯

  1. 特点:操作系统提供实现机制和编程接口,由用户在程序中实现,保证进程间可以进行快速的信息交换和大量数据的共享。但是,上述方式主要适合在同一台计算机系统内部的进程之间的通信
  2. 在UNIX中,信号灯是一组进程共享的数据结构,当几个进程竞争同一资源时(文件、共享内存或消息队列等),它们的操作便由信号灯来同步,以防止互相干扰。信号灯保证了某一时刻只有一个进程访问某一临界资源,所有请求该资源的其它进程都将被挂起,一旦该资源得到释放,系统才允许其它进程访问该资源。信号灯通常配对使用,以便实现资源的加锁和解锁。
  3. 使用外设的时候


套接字(socket)

套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。

套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。(参考:https://www.jianshu.com/p/c1015f5ffa74)





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值