华为内部面试题库(10)

摘要:
旋转锁的特点:1.低开销锁定;2.短期锁定;3.可用于锁定中断上下文;4.只能获得一个任务。自旋锁用于多个内核之间的同步,因此必须禁止抢占,否则很容易发生死锁。由此可以得出结论:C错误,获取自旋锁的代码不能被抢占。

1. 对于linux内核信号量,说法正确的是(多选):(参考:Linux内核设计与实现,第二版,第9章,9.4小节)

A. 如果获取一个被占用的信号量,任务会睡眠,等待信号量释放之后,该任务才能重新获得调度

B. 信号量可以允许任意数量的锁持有者

C. 信号量保护的代码可以被抢占

D. 信号量的实现也是与体系架构相关的

答案:A,B,C,D

试题解析:信号量是一个睡眠锁,在信号量被占用时,企图获取该信号量的任务会睡眠,等待信号量被释放,或者被唤醒,之后再重新获得调度;

信号量在初始化时,其count可以初始化为大于等于0的任何数值,因此可以允许任意数量的锁持有者;

信号量获取后,在释放之前,并不管抢占,正因为这个原因,在可抢占的内核中,高优先级任务可以抢占获取信号量的低优先级任务;

在内核中,信号量数据结构如下:

struct semaphore {

       spinlock_t              lock;

       unsigned int           count;

       struct list_head       wait_list;

};

自旋锁保护P/V(对其count加减)操作,而自旋锁是基于原子操作才能实现,因此信号量是与体系架构相关的。

 

2. 对于内核信号量,对其使用方法,错误的是(单选):(参考:Linux内核设计与实现,第二版,第9章,9.4小节)

A. 信号量在使用之前一定要初始化,否则在使用时可能会导致内核崩溃

B. 对信号量的操作,其实就是P/V操作,在linux内核中,对信号量的down()相当于V操作,up()相当于P操作

C. 在使用down_interruptible()函数未获取信号量时,进入睡眠的任务可以被信号唤醒

D. 如果想在获取信号量失败后超时退出,可以使用down_timeout()函数接口

答案:B

试题解析:内核信号量以及内核mutex,在使用之前都需要初始化,内核对信号量的初始化,方法有:

1.  sema_init(struct semaphore *sem, int val),将count的值初始化为val;

2. init_MUTEX(sem), count的值初始化为1,通常用于互斥操作;

3. init_MUTEX_LOCKED(sem), count的值初始化为0,通常用于异步事件的同步;

linux内核中,对信号量的down()相当于P操作,up()相当于V操作

down_interruptible()以及down_timeout()接口函数,可参考内核代码。

因此选B

 

3. 对于信号量和自旋锁使用区别,错误的是(单选):(参考:Linux内核设计与实现,第二版,第9章,9.4小节)

A. 信号量适合于多进程对资源互斥,竞争失败就会发生上下文切换,适合进程长时间占用资源;

B. 如果占用资源时间短于线程上下文切换开销时间,使用自旋锁

C. 在使用信号量和自旋锁时,持有信号量或者自旋锁的代码可以被高优先级任务抢占

D. 如果需要在中断上下文中保护临界区,则只能使用spinlock,不能使用信号量

答案:C

试题解析:信号量特点:

1. linux中的信号量是一种睡眠锁,当一个任务试图获得一个已经被占用的信号量,信号量会将其推进一个等待队列,然后让其睡眠。

2. 争用信号量的进程在等待锁可用时会睡眠,使用锁长时间持有的情况;

3. 允许任意数量持有该锁。

自旋锁特点:

1. 低开销加锁;

2. 短期锁定;

3. 可用于中断上下文中加锁;

4. 只允许一个任务获取。

自旋锁用于多核之间的同步,因此需要禁止抢占,否则很容易造成死锁(如在本地CPU上任务被抢占,在高优先级任务中又获取了同一个自旋锁,死锁)由此得出:C错误,获取自旋锁的代码不能被抢占。

 

4. 下面不是解决linux内核态并发机制的是(单选):(参考:Linux内核设计与实现,第二版,第9章)

A. 自旋锁;

B. 互斥锁mutex

C. 原子操作

D. 管道

答案:D

试题解析:管道是一种用户态进程间通信机制。管道是进程之间的一个单向数据流:一个进程写入管道的所有数据都由内核定向到另一个进程,另一个进程由此就可以从管道中读取数据。

 

5. 下面不是内核态和用户态间通信机制的是(单选)(参考:http://www.ibm.com/developerworks/cn/linux/l-netlink/index.html)

A. Netlink

B. 消息队列

C. 系统调用

D. ioctl

答案:B

试题解析:消息队列是一种用户态进程间通信机制,不能实现内核态和用户态间通信;

Netlink,系统调用,ioctl是使用较多的内核态和用户态间通信机制,其中系统调用只能由用户态发起。

免责声明:文章转载自《华为内部面试题库(10)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Windows I/O完成端口剑指 Offer 19. 正则表达式匹配下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Code Tips: 线程读写锁自旋导致的死循环

发现问题        项目测试的时候,发现运行一段时间后会出现cpu百分之百的情况。     想着可能是哪里出现了死循环,于是打算用gdb跟一下,结果gdb居然无法attach到进程。 定位问题     查了查去,原来有一个优先级为RT的实时线程出现了死循环,并且由于配置了CPU的亲和属性,使得进程只运行在第一个核上,此时gdb就无法attach了   ...

Zynq 7020笔记之 GPIO MIO 和EMIO的学习

1 参考 Xilinx ZYNQ 7000+Vivado2015.2系列(四)之GPIO的三种方式:MIO、EMIO、AXI_GPIO 2 理论指示 在PS侧,有PS自己的IO pin,称为MIO,共有54个(编号0-53)。如果PS侧IO不够使用,则可以通过扩展的方式来使用PL侧的IO。扩展方式有两中:EMIO和GPIO。 EMIO 方式可以将PL侧IO...

面渣逆袭:HashMap追魂二十三问

大家好,我是老三。 HashMap作为我们熟悉的一种集合,可以说是面试必考题。简单的使用,再到原理、数据结构,还可以延伸到并发,可以说,就一个HashMap,能聊半个小时。 1.能说一下HashMap的数据结构吗? JDK1.7的数据结构是数组+链表,JDK1.7还有人在用?不会吧…… 说一下JDK1.8的数据结构吧: JDK1.8的数据结构是数组+链表+...

为代码编写稳定的单元测试 [Go]

为代码编写稳定的单元测试 本文档配套代码仓库地址: https://github.com/liweiforeveryoung/curd_demo 配合 git checkout 出指定 commit 以及 git diff 比较 commit 间的差别食用更佳 单元测试的作用 功能交付的保障,确保不会发生一些低级错误,只要你觉得哪处逻辑在某种 case...

C99规范

1. 增加restrict指针    C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restrict数据类型不改变程序的语义。    如果某个函数定义了两个restr...

c++对象初始化中 ZeroMemory、memset、直接赋0的区别

首先是ZeroMemory和memset的区别: 1、ZeroMemory是微软的SDK提供的,memset属于C Run-time Library提供的。因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统。 2、ZeroMemory是一个宏,只是用于把一段内存的内容置零,内部其实是用 memset实现的,而memset除...