笔试总结1

1.Linux IPC(Inter-Process Communication,进程间通信)

 

linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。Linux则把两者继承了下来,如图示:

其中,最初Unix IPC包括:管道、FIFO、信号;System V IPC包括:System V消息队列、System V信号灯、System V共享内存区;Posix IPC包括: Posix消息队列、Posix信号灯、Posix共享内存区。

 

(1) 管道
半双工,可以有关系或无关系的进程间使用,FIFO(特殊文件),使用时管道的读写规则如读写打开,读写过程,阻塞读写,有较多地方需要注意!
(2) 信号
  异步方式,可靠和不可靠,kill,raise(向自身发送信号),sigqueue(支持信号带参数,之前可以配置信号处理函数),alarm(只有SIGALRM信号),settimer(更加强大的定时器),abort(SIGABORT信号)
  信号安装靠signal和sigaction(与sigqueue配合)
(3 )消息队列
消息队列与管道以及有名管道相比,具有更大的灵活性,首先,它提供有格式字节流,有利于减少开发人员的工作量;其次,消息具有类型,在实际应用中,可作为优先级使用。这两点是管道以及有名管道所不能比的。同样,消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。
(4) 信号灯
  可以说不是一种纯粹的进程间通信,更加侧重于对进程间共享资源的访问控制。而且这种控制可以由其他进程来修改。
semaphores aren't just thread-safe, they're even signal-safe. If for some reason you have to use thread synchronization inside signal handlers, they have to be semaphores. Otherwise you'll cause deadlocks.
(5) 共享内存
  最快的IPC方式,但是要考虑被拿来map的文件的存在问题,同时,多个进程操作共享内存也要保证一致性,除此以外,共享内存的大小也有限制,还有map后不能越页访问!!
(6) 网络(套接字)
  多机器间的进程通信

2.arm的7种处理器模式

因为arm有7种处理器模式,(用户usr、中断irq、快中断fiq、管理svc、中止abt、未定义und、系统sys),37个寄存器中是这样分的:
r0~r7是通用的,就是其中模式都可以用;
r8~r12分两组,就是有10个了,快中断模式用一组(r8_fiq~r12_fiq),其余的六种模式用一组(r8~r12);
r13、r14分六组,就是有12个,其中用户模式和系统模式共用一组(r13~r14),其余的5种模式各有一组【r13_irq~r14_irq】【r13_fiq~r14_fiq】【r13_svc~r14_svc】【r13_abt~r14_abt】【r13_und~r14_und】;
r15为七种模式共用;
程序状态寄存器:cpsr是共用的,spsr也是分了组的,但是只有5个,因为在用户模式和系统模式下不需要spsr。
所以arm状态下每种模式是18个可用(用户模式和系统模式是17个)。

thumb状态类推。因为thumb状态下没有用到r8-r12寄存器。

3.返回函数指针的函数

 

1) 定义函数指针:
return_type (*func_pointer)(parameter_list)
2) 定义返回函数指针的函数:
return_type(*function(func_parameter_list))(parameter_list)
定义了一个函数function,该函数的参数列表是(function_patameter_list),返回类型是一个函数指针,这个函数指针的原型是return_type(*)(parameter_list)。

所以如果要定义一个函数指针,指向的函数有两个int形参并且返回一个函数指针,返回的指针指向一个int形参返回int的函数:

int (*(*F)(int,int))(int)

4.typedef union{

struct field_def{

int a:1;

int b:2;

int c:3;

}fileds;

int data;

}REG_DEF;

REG_DEF reg;reg.data = 6,那reg.fileds.b=?

6=000110(二),a只有一位对应于右边的0,b有2位对应11(二),即为3.

5.用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里
  重新读取它的值,并不要随意针对它作优化。
  建议使用volatile变量的场所:
  (1) 并行设备的硬件寄存器
  (2) 一个中断服务子程序中会访问到的非自动变量(全局变量)
  (3) 多线程应用中被几个任务共享的变量

6.

内核空间和用户空间是操作系统理论的基础之一,即内核功能模块运行在内核空间,而应用程序运行在用户空间。现代的CPU都具有不同的操作模式,代表不同的级别,不同的级别具有不同的功能,在较低的级别中将禁止某些操作。Linux系统设计时利用了这种硬件特性,使用了两个级别,最高级别和最低级别,内核运行在最高级别(内核态),这个级别可以进行所有操作,而应用程序运行在较低级别(用户态),在这个级别,处理器控制着对硬件的直接访问以及对内存的非授权访问。内核态和用户态有自己的内存映射,即自己的地址空间。

正是有了不同运行状态的划分,才有了上下文的概念。用户空间的应用程序,如果想要请求系统服务,比如操作一个物理设备,或者映射一段设备空间的地址到用户空间,就必须通过系统调用来(操作系统提供给用户空间的接口函数)实现。如下图所示:

通过系统调用,用户空间的应用程序就会进入内核空间,由内核代表该进程运行于内核空间,这就涉及到上下文的切换,用户空间和内核空间具有不同的地址映射,通用或专用的寄存器组,而用户空间的进程要传递很多变量、参数给内核,内核也要保存用户进程的一些寄存器、变量等,以便系统调用结束后回到用户空间继续执行,所谓的进程上下文,就是一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容,当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。

同理,硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理,中断上下文就可以理解为硬件传递过来的这些参数和内核需要保存的一些环境,主要是被中断的进程的环境。

Linux内核工作在进程上下文或者中断上下文。提供系统调用服务的内核代码代表发起系统调用的应用程序运行在进程上下文;另一方面,中断处理程序,异步运行在中断上下文。中断上下文和特定进程无关。

运行在进程上下文的内核代码是可以被抢占的(Linux2.6支持抢占)。但是一个中断上下文,通常都会始终占有CPU(当然中断可以嵌套,但我们一般不这样做),不可以被打断。正因为如此,运行在中断上下文的代码就要受一些限制,不能做下面的事情:

1、睡眠或者放弃CPU。

      这样做的后果是灾难性的,因为内核在进入中断之前会关闭进程调度,一旦睡眠或者放弃CPU,这时内核无法调度别的进程来执行,系统就会死掉

2、尝试获得信号量

      如果获得不到信号量,代码就会睡眠,会产生和上面相同的情况

3、执行耗时的任务

      中断处理应该尽可能快,因为内核要响应大量服务和请求,中断上下文占用CPU时间太长会严重影响系统功能。

4、访问用户空间的虚拟地址

      因为中断上下文是和特定进程无关的,它是内核代表硬件运行在内核空间,所以在终端上下文无法访问用户空间的虚拟地址

 

最后欢迎大家访问我的个人网站: 1024s

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值