当前位置:文档之家› Linux信号量机制编程设计说明书

Linux信号量机制编程设计说明书

Linux信号量机制编程设计说明书
Linux信号量机制编程设计说明书

Linux信号量机制编程设计说明书

1课程设计的目的及要求

1.1课程设计的目的

某寺庙中有小和尚、老和尚若干人。庙有一水缸,由小和尚提水入缸,供老和尚饮用。水缸可容纳 30 桶水,每次入水、取水仅为 1 桶,不可同时进行。水取自同一水井,水井路窄,每次只能容纳一个水桶取水,设水桶个数为 5 个。和尚挑水问题就是使用某种机制,能够使得若干名老和尚可以顺利地喝到水,若干名小和尚之间能够有条不紊地往水缸中入水。

本课程设计的目的是使用Linux的信号量机制编程解决和尚挑水问题,通过本课程设计掌握Linux进程创建的方法,掌握信号量的使用方法。

1.2课程设计的要求

本课题所设计的系统要现以下功能。

编写 2 个程序,程序 1 创建 3 个子进程,分别编号 A、B、C,用于模拟 3 名老和尚;程序 2 创建 3 个子进程,分别编号 C、D、E,用于模拟 3名小和尚。通过向屏幕输出语句模拟取水过程,如输出“目前水缸水量为 10 桶”表示目前水缸中有存水 10桶;输出“小和尚取水成功”表示从水井中成功取到 1 桶水;输出“小和尚倒 1 桶水到水缸中”表示小和尚将 1 桶水倒入水缸

中。通过观察输出语句,可以发现执行过程是否发成冲突。

使用 Linux 的信号量机制,编写解决和尚挑水问题的代码。

要求给出编译所用到的 makefile 文件。

2准备工作

2.1硬件及软件需要

CentOS6.4

gcc编译器

vim编辑器

2.2了解信号量及信号量的系统调用函数:

2.2.1信号量定义

最简单的信号量是一个只有0与1两个值的变量,二值信号量。这是最为通常的形式。具有多个正数值的信号量被称之为通用信号量。在本章的其余部分,我们将会讨论二值信号量。

P与V的定义出奇的简单。假定我们有一个信号量变量sv,两个操作定义如下:

P(sv) 如果sv大于0,减小sv。如果sv为0,挂起这个进程的执行。

V(sv) 如果有进程被挂起等待sv,使其恢复执行。如果没有进行被挂起等待sv,增加sv。

信号量的另一个理解方式就是当临界区可用时信号量变量sv 为true,当临界区忙时信号量变量被P(sv)减小,从而变为false,

当临界区再次可用时被V(sv)增加。注意,简单的具有一个我们可以减小或是增加的通常变量并不足够,因为我们不能用C,C++或是其他的编程语言来表述生成信号,进行原子测试来确定变量是否为true,如果是则将其变为false。这就是使得信号量操作特殊的地方。

信号量函数定义如下:

#include

intsemctl(intsem_id, intsem_num, int command, .. .);

intsemget(key_t key, intnum_sems, intsem_flags);

intsemop(intsem_id, structsembuf *sem_ops, size_t num_sem_ops);

事实上,为了获得我们特定操作所需要的#define定义,我们需要在包含sys/sem.h文件之前通常需要包含sys/types.h与sys/ipc.h文件。而在某些情况下,这并不是必须的。

因为我们会依次了解每一个函数,记住,这些函数的设计是用于操作信号量值数组的,从而会使用其操作向比单个信号量所需要的操作更为复杂。

注意,key的作用类似于一个文件名,因为他表示程序也许会使用或是合作所用的资源。相类似的,由semget所返回的并且为其他的共享存函数所用的标识符与由fopen函数所返回的FILE *十分相似,因为他被进程用来访问共享文件。而且与文件类似,不同的进程会有不同的信号量标识符,尽管他们指向相同的信号量。key与标识符的用法对于在这里所讨论的所有IPC程序都是通用的,尽管每一个程序会使用独立的key与标识符。

2.2.1信号量集得创建与打开semget()

semget函数创建一个新的信号量或是获得一个已存在的信号量键值。

调用原型:int semget(key_t key,int num_sems,int sem_flags);

第一个参数key是一个用来允许不相关的进程访问相同信号量的整数值。所有的信号量是为不同的程序通过提供一个key来间接访问的,对于每一个信号量系统生成一个信号量标识符。信号量键值只可以由semget获得,所有其他的信号量函数所用的信号量标识符都是由semget所返回的。

还有一个特殊的信号量key值,IPC_PRIVATE(通常为0),其作用是创建一个只有创建进程可以访问的信号量。这通常并没有有用的目的,而幸运的是,因为在某些Linux系统上,手册页将IPC_PRIVATE并没有阻止其他的进程访问信号量作为一个bug列出。

num_sems参数是所需要的信号量数目。这个值通常总是1。

sem_flags参数是一个标记集合,与open函数的标记十分类似。低九位是信号的权限,其作用与文件权限类似。另外,这些标记可以与IPC_CREAT进行或操作来创建新的信号量。设置IPC_CREAT标记并且指定一个已经存在的信号量键值并不是一个错误。如果不需要,IPC_CREAT标记只是被简单的忽略。我们可以使用IPC_CREAT与IPC_EXCL的组合来保证我们可以获得一个新的,唯一的信号量。如果这个信号量已经存在,则会返回一个错误。

如果成功,semget函数会返回一个正数;这是用于其他信号量函数的标识符。如果失败,则会返回-1。

2.2.2信号量的操作semop()

函数semop用来改变信号量的值:

调用原型:int semop(int sem_id,struct sembuf*semops, size_tnum_sem_ops);

第一个参数,sem_id,是由semget函数所返回的信号量标识符。

第二个参数,sem_ops,是一个指向结构数组的指针,其中的每一个结构至少包含下列成员:

structsembuf

{

short sem_num;

short sem_op;

short sem_flg;

}

第一个成员,sem_num,是信号量数目,通常为0,除非我们正在使用一个信号量数组。sem_op成员是信号量的变化量值。(我们可以以任何量改变信号量值,而不只是1)通常情况下中使用两个值,-1是我们的P操作,用来等待一个信号量变得可用,而+1是我们的V操作,用来通知一个信号量可用。

最后一个成员,sem_flg,通常设置为SEM_UNDO。这会使得操作系统跟踪当前进程对信号量所做的改变,而且如果进程终止而没有释放这个信号量,如果信号量为这个进程所占有,这个标记可以使得操作系统自动释放这个信号量。将sem_flg设置为SEM_UNDO是一个好习惯,除非我们需要不同的行为。如果我们确实变我们需要一个不同的值而不是SEM_UNDO,一致性是十分重要的,否则我们就会变得十分迷惑,当我们的进程退出时,核是否

会尝试清理我们的信号量。

semop的所用动作会同时作用,从而避免多个信号量的使用所引起的竞争条件。

2.2.3信号量的控制semctl()

semctl函数允许信号量信息的直接控制

调用原型:int semctl(int sem_id,int sem_num,int command,...);

第一个参数,sem_id,是由semget所获得的信号量标识符。sem_num参数是信号量数目。当我们使用信号量数组时会用到这个参数。通常,如果这是第一个且是唯一的一个信号量,这个值为0。command参数是要执行的动作,而如果提供了额外的参数,则是union semun,根据X/OPEN规,这个参数至少包括下列参数:union semun {

intval;

structsemid_ds *buf;

unsigned short *array;

}

许多版本的Linux在头文件(通常为sem.h)中定义了semun联合,尽管X/Open确认说我们必须定义我们自己的联合。

有多个不同的command值可以用于semctl。在这里我们描述两个会经常用到的值。

这两个通常的command值为:

SETVAL:用于初始化信号量为一个已知的值。所需要的值作为联合semun的val成员来传递。在信号量第一次使用之前需要设置信号量。

第3章部分习题答案 3.2. 为什么进程在进入临界区之前,应先执行"进入区"代码,在退出临界区后又执行"退出区"代码? 为了实现多个进程对临界资源的互斥访问,必须在临界区前面增加一段用于检查欲访问的临界资源是否正被访问的代码,如果未被访问,该进程便可进入临界区对资源进行访问,并设置正被访问标志,如果正被访问,则本进程不能进入临界区,实现这一功能的代码成为"进入区"代码;在退出临界区后,必须执行"退出区"代码,用于恢复未被访问标志. 3.3 同步机构应遵循哪些基本准则?为什么? a. 空闲让进. b. 忙则等待. c. 有限等待. d. 让权等待. 3.6你认为整型信号量机制和记录型信号量机制,是否完全遵循了同步机构的四条准则? a. 在整型信号量机制中,未遵循"让权等待"的准则. b. 记录型信号量机制完全遵循了同步机构的"空闲让进,忙则等待,有限等待,让权等待"四条准则. 3.9在生产者-消费者问题中,如果缺少了signal(full)或signal(empty),对执行结果会有何影响? 生产者-消费者问题可描述如下: var mutex,empty,full: semaphore:=1,n,0; buffer: array[0,...,n-1] of item; in,out: integer:=0,0; begin parbegin producer: begin repeat . . produce an item in nextp; . . wait(empty); wait(mutex); buffer(in):=nextp; in:=(in+1) mod n; signal(mutex); /* ************** */ signal(full); /* ************** */ until false; end consumer: begin repeat wait(full); wait(mutex); nextc:=buffer(out); out:=(out+1) mod n; signal(mutex); /* ************** */

第1章习题及解答略 第2&6章习题及解答 1.判断正误 (1)凡频谱是离散的信号必然是周期信号。( ×)准周期信号 (2)任何周期信号都由频率不同,但成整倍数比的离散的谐波叠加而成。( ×) (3)周期信号的频谱是离散的,非周期信号的频谱也是离散的。( ×) (4)周期单位脉冲序列的频谱仍为周期单位脉冲序列。( √) (5)非周期变化的信号就是随机信号。( ×)准周期信号 (6)非周期信号的幅值谱表示的是其幅值谱密度与时间的函数关系。( ×) (7)信号在时域上波形有所变化,必然引起频谱的相应变化。( ×) (8)各态历经随机过程是平稳随机过程。( √) (9)平稳随机过程的时间平均统计特征等于该过程的集合平均统计特征。( √) (10)非周期信号的频谱都是连续的。( ×) 准周期信号 (11)单位脉冲信号的频谱是无限带宽谱(√) (12)直流信号的频谱是冲击谱(√) 2.选择正确答案填空 (1)描述周期信号的数学工具是(B )。 A.相关函数 B. 傅里叶级数 C. 拉普拉斯变换 D. 傅里叶变换 (2)描述非周期信号的数学工具是( C)。 A.三角函数 B. 拉普拉斯变换 C. 傅里叶变换 D. 傅里叶级数

(3) 将时域信号进行时移,则频域信号将会( D ) A.扩展 B. 压缩 C. 不变 D. 仅有相移 (4) 瞬变信号的傅里叶变换的模的平方的意义为( C ) A.信号的一个频率分量的能量 B. 在f 处的微笑频宽内,频率分量的能量与频宽之比 C. 在f 处单位频宽中所具有的功率 (5) 概率密度函数是在(C )域,相关函数是在(A )域,功率谱密度函数是 在( D )域描述随机信号。 A.时间 B. 空间 C. 幅值 D. 频率 (6) 白噪声信号的自相关函数是(C ) A.相关函数 B. 奇函数 C. 偶函数 D. 不存在 6.4已知被测模拟量最大输出幅值为±5V ,要求AD 转换输出最大误差不大于5mv ,应选用多少位的AD 转换器? 解:量化误差5mv=±0.5LSB=125*5.012* 5.0-±=-±n n V FS 解得n=9 6.6 模拟信号DFT ,请问采样时间间隔Δt 、采样点数N 、频率分辨率Δf 三者之间的关系?并回答如下问题: (1) 为什么采样频率Δf 必须至少为被分析信号中最高频率成分的2倍才能避免混淆? (2) 当采样频率确定后,频谱中应该出现的最高频率是多少? (3) 频谱中的谱线根数是否与时域中的采样点数相同?对于频谱分析来说有用的谱线根数是多少?

实验四 Linux进程互斥 一、实验目的 熟悉Linux下信号量机制,能够使用信号量实现在并发进程间的互斥和同步。 二、实验题目 使用共享存储区机制,使多个并发进程分别模拟生产者-消费者模式同步关系、临界资源的互斥访问关系,使用信号量机制实现相应的同步和互斥。 三、背景材料 (一)需要用到的系统调用 实验可能需要用到的主要系统调用和库函数在下面列出,详细的使用方法说明通过“man 2 系统调用名”或者“man 3 函数名”命令获取。 fork() 创建一个子进程,通过返回值区分是在父进程还是子进程中执行; wait() 等待子进程执行完成; shmget() 建立一个共享存储区; shmctl() 操纵一个共享存储区; s hmat() 把一个共享存储区附接到进程内存空间; shmdt() 把一个已经附接的共享存储区从进程内存空间断开; semget() 建立一个信号量集; semctl() 操纵一个信号量集,包括赋初值; semop() 对信号量集进行wait和signal操作; signal() 设置对信号的处理方式或处理过程。 (二)模拟生产者-消费者的示例程序 本示例主要体现进程间的直接制约关系,由于使用共享存储区,也存在间接制约关系。进程分为服务进程和客户进程,服务进程只有一个,作为消费者,在每次客户进程改变共享存储区内容时显示其数值。各客户进程作为生产者,如果共享存储区内容已经显示(被消费),可以接收用户从键盘输入的整数,放在共享存储区。 编译后执行,第一个进程实例将作为服务进程,提示: ACT CONSUMER!!! To end, try Ctrl+C or use kill. 服务进程一直循环执行,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。 其他进程实例作为客户进程,提示: Act as producer. To end, input 0 when prompted. 客户进程一直循环执行,直到用户输入0。 示例程序代码如下: #include #include #include #include #include #include #include #include

计算机操作系统典型例题解析之三 【例1】分配到必要的资源并获得处理机时的进程状态是(B )。A、就绪状态B、执行状态 C、阻塞状态D、新状态 分析:进程有三种基本状态:就绪状态、执行状态和阻塞状态。当进程已分配到除CPU以外的所有必要的资源后,只要能再获得处理机便可立即执行,这时的状态称为就绪状态;处于就绪状态的进程如果获得了处理机,其状态转换为执行状态;进程因发生某种事件(如I/O请求、申请缓冲空间等)而暂停执行时的状态,亦即进程的执行受到阻塞,故称这种状态为阻塞状态;而新状态是指创建了进程但尚未把它插入到就绪队列前的状态。所以本题的答案是B。 【例2】挂起的进程被激活,应该使用(C)原语。 A、Create B、Suspend C、Active D、Wakeup 分析:在不少系统中,进程除了三种基本状态外,又增加了一些新的状态,其中最重要的是挂起状态。“挂起”的实质是使进程不能继续执行,即使挂起后的进程处于就绪状态,它也不能参加对CPU的竞争,进程的挂起调用Suspend()原语。因此,被挂起的进程处于静止状态,相反,没有挂起的进程则处于活动状态。而且,处于静止状态的进程,只有通过“激活”动作,调用Active()原语,才能转换成活动状态,调入内存。所以本题的答案是C。 【例3】任何时刻总是让具有最高优先数的进程占用处理器,此时采用的进程调度算法是(D)。A非抢占式的优先数调度算法B、时间片轮转调度算法C、先来先服务调度算法D、抢占式的优先

数调度算法 分析:“让具有最高优先数的进程占用处理器”,我们可以知道,采用的进程调度算法是优先数调度算法,但是我们还要进一步分析是抢占式的还是非抢占式的。“任何时刻总让”,通过这句话我们知道采用的是抢占式的,所以本题的答案是D。 【例4】若P、V操作的信号量S初值为2,当前值为-1,则表示有(B)等待进程。A、0个B、1个C、2个D、3个分析:信号量的初始值表示系统中资源的数目,每次的Wait操作意味着进程请求一个单位的资源,信号量进行减1的操作,当信号量小于0时,表示资源已分配完毕,进程自我阻塞。因此,如果信号量小于0,那么信号量的绝对值就代表当前阻塞进程的个数。所以本题的答案是B。 【例5】发生死锁的必要条件有四个,要预防死锁的发生,可以破坏这四个必要条件,但破坏(A)条件是不太实际的。 A、互斥 B、请求和保 C、不剥夺 D、环路等待 分析:预防死锁是指通过破坏死锁的某个必要条件来防止死锁的发生。四个必要条件中,后三个条件都可以被破坏,而第一个条件,即“互斥”条件,对某些像打印机这样的设备,可通过SPOOLing技术予以破坏,但其他资源,因受它们的固有特性的限制,该条件不仅不能被破坏,反而应加以保证。所以本题的答案是A。 【例6】有m个进程共享同一临界资源,若使用信号量机制实现对临界资源的互斥访问,则信号量值的变化范围是1 至1-m。

Linux 期末考试试题(一) 一、选择题 (每小题2分,共50分) 1.在创建Linux分区时,一定要创建(D )两个分区 A. FAT/NTFS B. FAT/SWAP C. NTFS/SWAP D.SW AP/根分区 2.在Red Hat Linux 9中,系统默认的(A)用户对整个系统拥有完全的控制权。 A. root B. guest C. administrator D.supervistor. 3. 当登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么( B ) A. NID B. PID C. UID D. CID 4. 下面哪个命令是用来定义shell的全局变量( D ) A. exportfs B. alias C. exports D. export 5. 哪个目录存放用户密码信息( B ) A. /boot B. /etc C. /var D. /dev 6. 默认情况下管理员创建了一个用户,就会在( B )目录下创建一个用户主目录。 A. /usr B. /home C. /root D. /etc 7. . 当使用mount进行设备或者文件系统挂载的时候,需要用到的设备名称位于( D )目录。 A. /home B. /bin C. /etc D. /dev 8. 如果要列出一个目录下的所有文件需要使用命令行( C )。 A. ls –l B. ls C. ls –a(所有) D. ls –d 9. 哪个命令可以将普通用户转换成超级用户(D ) A. super B. passwd C. tar D. su 10. 除非特别指定,cp假定要拷贝的文件在下面哪个目录下( D ) A. 用户目录 B. home目录 C. root目录 D. 当前目录 11. 在vi编辑器里,命令"dd"用来删除当前的( A ) A. 行 B. 变量 C. 字 D. 字符 12. 当运行在多用户模式下时,用Ctrl+ALT+F*可以切换多少虚拟用户终端( B ) A. 3 B. 6 C. 1 D. 12 13. Linux启动的第一个进程init启动的第一个脚本程序是( B )。 A./etc/rc.d/init.d B./etc/rc.d/rc.sysinit C./etc/rc.d/rc5.d D./etc/rc.d/rc3.d 14. 按下(A )键能终止当前运行的命令 A. Ctrl-C B. Ctrl-F C. Ctrl-B D. Ctrl-D 15. 下面哪个命令用来启动X Window ( C ) A. runx B. Startx C. startX D. xwin 16. 用来分离目录名和文件名的字符是( B ) A. dash (-) B. slash (/) C. period (.) D. asterisk(*) 17. 用"rm -i",系统会提示什么来让你确认( B ) A. 命令行的每个选项 B. 是否真的删除 C. 是否有写的权限 D. 文件的位置 18. 以下哪个命令可以终止一个用户的所有进程( D ) A. skillall B. skill C. kill D. killall 19.在Red Hat Linux 9中,一般用(D )命令来查看网络接口的状态 A. ping B. ipconfig C. winipcfg D ifconfig 20. vi中哪条命令是不保存强制退出( C )(第五章) A. :wq B. :wq! C. :q! D. :quit 21.局域网的网络设备通常有(ABCDE)

系统软件与软件工程本栏目责任编辑:谢媛媛Computer Knowledge and Technology 电脑知识与技术第6卷第12期(2010年4月)基于Linux 的信号量通信机制研究与实现 袁玉锦,周群 (邯郸学院网络中心,河北邯郸056005) 摘要:该文以信号量通信理论为基础,通过对Linux 信号量相关系统调用的分析,着重讨论了内核级和用户级的信号量通信、同一进程内线程之间的通信、多用户的进程间的通信等问题,并采用ANSI C 编写了信号量通信的具体实例。 关键词:信号量;Linux ;多进程通信;线程通信 中图分类号:TP316文献标识码:A 文章编号:1009-3044(2010)12-3279-03 1信号量通信理论 操作系统原理中利用信号量来解决多进程互斥访问临界资源的问题,还可来描述多进程之间的前趋关系,即同步问题。 信号量的概念由荷兰学者E.W.Dijkstra 于1965年提出。信号量实际是一个整数,进程(也可以是线程)在信号量上的操作分2种,一种称为P 操作,另一种称为V 操作。P 操作是让信号量的值减1,V 操作是让信号量的值加1。在进行实际的操作之前,进程首先检查信号量的当前值,如果当前值大于0,则可以执行P 操作,否则进程休眠,等待其他进程在该信号量上的V 操作,因为其他进程的V 操作将让信号量的值增加,从而它的P 操作可以成功完成。某信号量在经过某个进程的成功操作之后,其他休眠在该信号量上的进程就有可能成功完成自己的操作,这时系统负责检查休眠进程是否可以完成自己的操作。 在操作系统中,信号量最简单的形式也是最初被提出时定义的形式是一个整数,多个进程可检查并设置信号量的值。这种检查并设置(Test-and-Set)操作是不可中断的,也称为“原子”操作。检查并设置操作的结果是信号量的当前值和设置值相加的结果,该设置值可以是正值,也可以是负值。根据检查并设置操作的结果,进行操作的进程可能会进入休眠状态,而当其他进程完成自己的检查并设置操作后,由系统检查前一个休眠进程是否可以在新信号量值的条件下完成相应的检查并设置操作。这样,通过信号量,就可以协调多个进程的操作,实现多进程之间通信。 操作系统原理中通常把信号、信号量通信称为低级通信,而把管道、消息队列、共享存储区通信称为高级通信。信号量分为有名、无名两种,进程间通信用有名信号量,同一进程内部通信一般用无名信号量。 2Linux 中的信号量 从意义和实现机理上,Unix System V 或Linux 的信号量与以上所述的常规信号量没有什么区别,但System V 提供的信号量机制要复杂得多,并且分为两种不同系统调用类型:一种是用内核级的信号量,有关系统调用在/usr/include/semaphore.h 中包含,一般可用于内核级的进程通信和内核级的线程通信;另一种是用户级信号量,有关系统调用在/usr/include/sys/sem.h 中包含,一般可用于多用户进程之间通信。 2.1内核级的信号量相关系统调用 int sem_init (sem_t *sem ,int pshared ,unsigned int value) 作用:为单个信号量设置初值,第一参数*sem 为指定的信号量对象;第二参数pshared 为共享标志,如值为0表示私有信号量,非0表示可以与其他进程共享的信号量;第三参数value 为要为信号量设置的初值。 相关数据结构如下: struct{struct{long int status ; int spin_lock ;}sem_lock ; int sem_value ; pthread_descr sem_waiting ; }sem_t int sem_wait (sem_t *sem); 作用:对指定的信号量进行P 操作。 Int sem_post (sem_t *sem); 作用:对指定的信号量进行V 操作。 总结:以上是内核级信号量通信常用到的三个系统调用,使用方式较为简单,但主要适用于内核级多线程之间通信,后面将给出多线程通信的具体实例。 收稿日期:2010-02-21 作者简介:袁玉锦(1980-),女,河北曲周人,邯郸学院网络中心,助教,学士,研究方向为计算机网络;周群(1981-),女,河北武安 人,助教,学士,主要研究方向为计算机网络。 ISSN 1009-3044Computer Knowledge and Technology 电脑知识与技术Vol.6,No.12,April 2010,pp.3279-3281E-mail:xsjl@https://www.doczj.com/doc/e918429541.html, https://www.doczj.com/doc/e918429541.html, Tel:+86-551-569096356909643279

一、选择题 1.在创建Linux分区时,一定要创建(D )两个分区 A. FAT/NTFS B. FAT/SWAP C. NTFS/SWAP D.SW AP/根分区 2.在Red Hat Linux中,系统默认的(A)用户对整个系统拥有完全的控制权。 A. root B. guest C. administrator D.supervistor. 3. 当登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么( B ) A. NID B. PID C. UID D. CID 4. 下面哪个命令是用来定义shell的全局变量( D ) A. exportfs B. alias C. exports D. export 5. 哪个目录存放用户密码信息( B ) A. /boot B. /etc C. /var D. /dev 6. 默认情况下管理员创建了一个用户,就会在( B )目录下创建一个用户主目录。 A. /usr B. /home C. /root D. /etc 7. . 当使用mount进行设备或者文件系统挂载的时候,需要用到的设备名称位于( D )目录。 A. /home B. /bin C. /etc D. /dev 8. 如果要列出一个目录下的所有文件需要使用命令行( C )。 A. ls –l B. ls C. ls –a(所有) D. ls –d 9. 哪个命令可以将普通用户转换成超级用户(D ) A. super B. passwd C. tar D. su 10. 除非特别指定,cp假定要拷贝的文件在下面哪个目录下( D ) A. 用户目录 B. home目录 C. root目录 D. 当前目录 11. 在vi编辑器里,命令"dd"用来删除当前的( A ) A. 行 B. 变量 C. 字 D. 字符 12. 当运行在多用户模式下时,用Ctrl+ALT+F*可以切换多少虚拟用户终端( B ) A. 3 B. 6 C. 1 D. 12 13. Linux启动的第一个进程init启动的第一个脚本程序是( B )。 A./etc/rc.d/init.d B./etc/rc.d/rc.sysinit C./etc/rc.d/rc5.d D./etc/rc.d/rc3.d 14. 按下(A )键能终止当前运行的命令 A. Ctrl-C B. Ctrl-F C. Ctrl-B D. Ctrl-D 15. 下面哪个命令用来启动X Window ( C ) A. runx B. Startx C. startX D. xwin 16. 用来分离目录名和文件名的字符是( B ) A. dash (-) B. slash (/) C. period (.) D. asterisk(*) 17. 用"rm -i",系统会提示什么来让你确认( B ) A. 命令行的每个选项 B. 是否真的删除 C. 是否有写的权限 D. 文件的位置 18. 以下哪个命令可以终止一个用户的所有进程( D ) A. skillall B. skill C. kill D. killall 19.在Red Hat Linux 9中,一般用(D )命令来查看网络接口的状态 A. ping B. ipconfig C. winipcfg D ifconfig 20. vi中哪条命令是不保存强制退出( C )(第五章) A. :wq B. :wq! C. :q! D. :quit 21.局域网的网络设备通常有(ABCDE)

试用用信号量机制描述两人下象棋的过程。 两人下象棋的过程可以概括为:一开始只能是“红先黑后”,以后两人要循环轮流走子,直至某一方获胜或双方和棋为

止。? 这是个只有一个生产者和一个消费者的生产者——消费者问题,是个典型的“你等我,我也等你”的问题。红方是总的前趋任务——生产者进程,黑方是总的后继任务——消费者进程,但由于下棋过程必须轮流走子,所以红黑双方的生产者消费者身份会轮流改变。棋盘则是生产者与消费者共享的缓冲。?要求:只描述对弈过程,对棋盘的访问不做描述。二人对弈过程是个纯粹的同步过程 ①所用信号量设臵如下: Ⅰ)同步信号量hei,初值为1,表示黑方已走子,开始时可使红方先行不受阻。 Ⅱ)同步信号量hong,初值为0,表示红方尚未走子,开始时可使黑方先行受阻。 用信号量机制描述的二人下象棋过程如下

有一个阅览室,共有100个座位,读者进入时必须先在一张登记表上登记,该表为每一座位列一表目,包括座号和读者姓名等,读者离开时要消掉登记的信息,试问: (1)为描述读者的动作,应编写几个程序,设臵几个进程?(2)试用P、V操作描述读者进程之间的同步关系。分析:?读者的动作都是一样的:登记进入阅览室,阅读, 撤消登记离开阅览室,因此可写一个程序,设n个进程。 ?读者共享的资源有阅览室的座位和登记表,因此诸 个读者进程之间有两种互斥制约关系,需设2个信号量来实现:? seat:用于实现诸读者对阅览室的空闲座位的互斥 竞争,初值为100; ? mutex:用于实现诸读者对登记表的互斥访问,初值 为1

(1)可写一个程序,设n个进程 (2)读者进程readeri(i=1,2,3,……)描述如下: P(seat); /*申请空座位*/ P(mutex); /*申请登记*/ 登记; V(mutex) /*允许其他读者登记*/ 阅读; P(mutex); /*申请撤消登记*/ 撤消登记; V(mutex); /*允许其他读者撤消登记*/ V(seat); /*释放座位,允许他人进入*/

第6章信号量,中断和时间 信号量(Signal)是进程间通讯(IPC)的一种形式——是一个进程给另一个进程发送信息的方法。但是信息不可能很多——一个信号量不可能携带详细的信息,即使是传送者的身份也不能被传递;唯一能够确定的事实是信号量的确被发送了。(然而和经典信号量不同,POSIX实时信号量允许传送稍微多一点的信息。)实际上,信号量对于双向通讯是没有用处的。还有,根据某些限定,信号量的接受者不必以任何方式作出响应,甚至可以直接忽略大部分信号量。 虽然有这么多的限制,然而信号量仍然是一种功能强大的十分有用的机制——勿庸置疑,这是Unix IPC中使用最频繁的机制。每当进程退出或者废弃一个空指针时,每当使用Ctrl+C键终止程序运行时,都要传递信号量。 第9章会更详细的讨论IPC机制。对于本章的讨论来说,信号量的内容就足够讨论了。 正如在Linux内核本身的代码注释中所说明的一样,中断(Interrupt)对于内核来说和信号量是类似的。中断一般都是从磁盘之类的硬件设备送往内核,用以提示内核该设备需要加以注意。一个重要的硬件中断源就是定时器设备,它周期性地通知内核已经通过的时间。如同第5章中阐述的一样,中断也可以由用户进程通过软件产生。 在本章中,我们首先讨论一下Linux中信号量和中断的实现,最后再浏览一下Linux的时间处理方式。 虽然内核对代码的要求标准非常严格,本章所涉及的代码仍然特别清晰明白。本章使用的一般方法是首先介绍相关的数据结构和它们之间的关系,接下来讨论操纵和查询它们的函数。 锁的概述 锁的基本思想是限制对共享资源的访问——共享资源包括共享的文件,共享的内存片,以及在一次只能由一个CPU执行的代码段。概括的说,在单处理器上运行的Linux内核并不需要锁,这是因为在编写Linux内核时就已经注意到要尽量避免各种可能需要锁的情况了。但是,在多处理器机器上,一个处理器有时需要防止其它处理器对它的有害的介入。 include/asm-i386/spinlock.h文件(从12582行开始)并不使用难看的#ifdef把所有对锁函数的调用封装起来,它包含一系列对单处理器平台(UP)基本为空的宏,然而在多处理器平台(SMP)上这些宏将展开成为实际代码。因而内核的其它代码对UP和SMP(当涉及到这种特性时)都是相同的,但是它们两个的效果却是迥然不同的。 第10章中涉及SMP的部分会对锁做深入的介绍。但是,由于你在代码中将到处都能够看到对锁宏的调用,特别是在本章所讨论到的代码中这一点尤为明显,所以你应该首先对宏的用途有初步了解——以及为什么现在在大多数情况下我们都可以安全地将其忽略(我们将在讨论的过程中对其中的异常情况进行说明)。 信号量 Linux内核将信号量分为两类: 非实时的(Nonrealtime)——大部分是些传统的信号量,例如SIGSEGV,SIGHUP

6. 算法题(共32个题目) 200348. 在信号量机制中,若P(S)操作是可中断的,则会有什么问题? 此题答案为:答: P(S)的操作如下: Begin S.Value:= S.Value-1; ① If S.Value<0 Then ② Begin Insert(*,S.L); Block(*) ③ End End. 若P(S)可中断的,例如进程A在执行了语句①之后从CPU上退 下了,假定此时S.Value=0;这时换另一进程B,B又将S.Value 的值减1使之为-1,在执行语句③时,B被阻塞;然后又换回A执行,由于A的"断点"是语句①之后,当它执行语句②时,由于这时S.Value已经是-1,故进程继续执行而被阻塞。这就出现了错误: 本来A操作P(S)操作后,S.Value=0,是不应该被阻塞的,现在却被阻塞了。 200350. 何谓临界区?下面给出的两个进程互斥的算法是安全的吗?为什么?

#define true; # define false; Int flag[2]; flag[1]=flag[2]=false; enter-crtsec(i) int i; { While(flag[1-i]) flag[i]=true; } feave-crtsec(i) Int i; { flag[i]=false; } process I; … Enter-crtsec(i); In critical section; Leave-crtsec(i);

此题答案为:答:一次仅允许一个进程使用的资源称为临界资源,在进程中对临界资源访问的程序段称为临界区。 从概念上讲,系统中各进程在逻辑上是独立的,它们可以按各自的速度向前推进。但由于它们共享某些临界资源,因而产生了临界区问题。对于具有临界区问题的并发进程,它们之间必须互斥,以保证不会同时进入临界区。 这种算法不是安全的。因为,在进入临界区的enter-crtsec()不是一个原语操作,如果两个进程同时执行完其循环(此前两个flag均为false),则这两个进程可同时进入临界区。 200353. 某车站售票厅,任何时刻最多可容纳20名购票者进入,当售票少于20名购票者时,则厅外的购票者可立即进入,否则需在外面等待。若把一个购票者看作一个进程,请回答下列问题: (1)用P、V操作管理这些并发进程时,应怎样定义信号量?写出信号量的初值以及信号量各种取值的含义。 (2)根据所定义的信号量,把应执行的P、V操作填入下述程序中,以保证进程能够正确地并发执行。 Cobegin PROCESS Pi(i=1,2,…) Begin 进入售票厅; 购票; 退出; End;

实验报告 Unix下C 课程名 称: 读者写者问题 实验项 目: 姓 名: 专 网络工程 业: 网络 班 级: 学 号:

指导老 师: 计算机科学与技术学院 实验教学中心 2013 年12 月22

目录

一、课程设计目的及意义 l.用信号量来实现读者写者问题。 2.理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。 3.通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。 二、课程设计内容 在windows或者linux环境下编写一个控制台应用程序,本次课程设计在操作系统:Linux下,使用的编程语言为C语言。该程序运行时能创建N个线程,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。用信号量和PV操作实现读者/写者问题。 三、总体设计 读者/写者问题的描述如下: 有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。以下假设共享数据区是文件。这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。这些条件具体来说就是: (1)任意多的读进程可以同时读这个文件; (2)一次只允许一个写进程往文件中写;

程访问文件; (4)写进程执行写操作前,应让已有的写者或读者全部退出。这说明当有读者在读文件时不允许写者写文件。 四、详细设计 读者-写者的读写限制 1)写-写互斥,即不能有两个写者同时进行写操作 2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写 3)读读允许,即可以有2个以上的读者同时读 将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件: (1)任意多的读进程可以同时读这个文件; (2)一次只允许一个写进程往文件中写;

用信号量机制实现的写者优先的算法如: Var Mut1,Mut2,Wmutex,Fmutex:Semaphore; Rcount,Wcount:integer; Mut1:=Mut2:=WMutex:=Fmutex:=1; Rcount:=Wcount:=0; //Fmutex --> 读者写者互斥 //WMutex --> 写者互斥 //Mut1 --> access to Rcount && 竞争Fmutex //Mut2 --> access to Wcount Writer:begin Wait(Mut1); Wcount:=Wcount+1; If Wcount=1 then Wait(Fmutex); //如有读者,写者阻塞在此处 Signal(Mut1); Wait(WMutex); 写操作; Signal(Wmutex); Wait(Mut1); Wcount:=Wcount-1; If Wcount=0 then Signal(Fmutex); Signal(Mut1); end Reader:begin Wait(Mut1); //读者需要先申请Mut1,如果有写者在等待Fmutex,则读者被阻塞,写者优先 Signal(Mut1); //立即释放Mut1,使写者可以随时申请到Mut1 Wait(Mut2); Rcount:=Rcount+1; If Rcount=1 then Wait(Fmutex); //第一个读者进入时,申请Fmutex;如有写者,第一个读者会阻塞在此处 Signal(Mut2); 读操作; Wait(Mut2); Rcount:=Rcount-1; If Rcount=0 then Signal(Fmutex); //最后一个读者退出时,释放Fmutex Singal(Mut2); end

第三章进程管理练习题 一、选择题 1.如果信号量S的值是0,此时进程A执行P(S)操作,那么,进程A会()。 A.继续运行 B.进入阻塞态,让出CPU C.进入就绪态,让出CPU D.继续运行,并唤醒S队列头上的等待进程 2. 正在运行的进程在信号量S上操作P操作之后,当S<0,进程将进入信号量的()。 A.等待队列 B.提交队列 C.后备队列 D.就绪队列 3.在非剥夺调度方式下,运行进程执行V原语后,其状态()。 A.不变 B.要变 C.可能要变 D.可能不变 4. 一个进程被唤醒,意味着()。 A.改进程重新占有了CPU B.进程状态变为就绪 C.它的优先权变为最大 D.其PCB移至就绪队列的队首 5.. 系统感知进程的唯一实体是()。 A.JCB B.FCB C.PCB D.SJT 6. 一进程在某一时刻具有()。 A.一种状态 B.二种状态 C.三种状态 D.四种状态 7. 进程从运行状态变为等待的原因可能是()。 A.输入/输出事件发生 B.时间片到 C.输入/输出事件完成 D.某个进程被唤醒 8. 进程创建原语的任务是()。 A.为进程编制程序 B.为进程建立PCB表 C.为进程分配CPU D.为进程分配所需的各种资源 9. 进程被创建后即进入()排队。 A.阻塞队列 B.就绪队列 C.缓冲队列 D.运行队列 10.在操作系统中,进程是一个具有一定独立功能的程序在某个数据集上的一次。 A)等待活动 B)运行活动 C)单独操作 D)关联操作 11.下面对进程的描述中,错误的是。 A)进程是动态的概念 B)进程执行需要处理机 C)进程是有生命期的 D)进程是指令的集合

信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为: extern intsem_init __P ((sem_t *__sem, int __pshared, unsigned int __value)); sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。 函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。 函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。 函数sem_destroy(sem_t *sem)用来释放信号量sem。 信号量用sem_init函数创建的,下面是它的说明: #include intsem_init (sem_t *sem, intpshared, unsigned int value); 这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果pshared的值是0,就表示它是当前里程的局部信号量;否则,其它进程就能够共享这个信号量。我们现在只对不让进程共享的信号量感兴趣。(这个参数受版本影响),pshared传递一个非零将会使函数调用失败。 这两个函数控制着信号量的值,它们的定义如下所示: [cpp]view plaincopy 1.#include 2.int sem_wait(sem_t * sem); 3.int sem_post(sem_t * sem); 这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。 sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。 sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,

一、单选题 1、关于进程控制块的描述,如下存在问题的选项是()。 A.操作系统控制和管理并发执行进程的依据 B.进程存在的惟一标志,离散存放于内存空间或对应程序的文件目录项中 C.进程实体的一部分,是拥有描述进程情况及控制进程运行所需的全部信息的记录性数据结构 D.使一个在多道程序环境下不能独立运行的程序,成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程 正确答案:B 2、进程标识符和进程控制块的分配可能发生在进程的()阶段。 A.阻塞 B.挂起 C.创建 D.终止 正确答案:C 3、当一个进程被()时,可能会发生处理器的调度。 ①终止;②挂起;③唤醒;④阻塞 A.①②④ B.①③④ C.①②③④ D.①④ 正确答案:C

4、对于系统服务进程而言,如果当前没有任务,便会引发自身的()事件。 A.进程阻塞 B.进程唤醒 C.进程终止 D.进程挂起 正确答案:A 5、引起进程重新调度的原因不包括()。 A.进程放弃处理器 B.进程从核心态返回用户态 C.进程执行系统调用和陷入内核态 D.时钟中断 正确答案:C 6、关于进程同步机制基本准则:当无进程处于某临界资源所对应的临界区时,可允许一个请求进入(该临界资源所对应的)临界区的进程立即进入自己的临界区,这称之为()。 A.忙则等待 B.有限等待 C.空闲让进 D.让权等待 正确答案:C 7、关于进程同步机制基本准则:当已有进程进入自己的对应于某临界资源的临界区时,所有企图进入该临界资源所对应临界区的进程必须等待,这称之为()。 A.循环等待

B.忙则等待 C.有限等待 D.让权等待 正确答案:B 8、关于进程同步机制基本准则:对要求访问临界资源的进程,应保 证该进程能在有限时间内进入自己的临界区,这称之为()。 A.忙则等待 B.循环等待 C.有限等待 D.让权等待 正确答案:C 9、进程同步机制应遵循让权等待准则,故而当一个进程不能进入自 己的临界区时,其应当释放()。 A.处理器 B.I/O设备 C.内存空间 D.外存空间 正确答案:A 10、利用硬件指令能有效地实现进程互斥,但它却不能满足 ()的准则,造成了处理器时间的浪费,而且也很难将它用 于解决较复杂的进程同步问题。 A.忙则等待 B.空闲让进 C.让权等待 D.有限等待

利用信号量机制解决哲学家进餐问题

————————————————————————————————作者:————————————————————————————————日期:

成绩:课程设计报告 课程名称:课程设计(UNIX程序设计) 设计题目:利用信号量机制解决哲学家进餐问题 姓名: 专业:网络工程 班级: 学号: 计算机科学与技术学院 网络系 2013年12月28日

设计项目:利用信号量机制解决哲学家进餐问题 一、选题背景 1965年,数学家迪杰斯特拉提出,并成为经典的IPC问题—哲学家进餐问题。该问题的简单描述如下:五个哲学家围坐在一张圆桌周围,每个哲学家面前都一盘通心粉。由于通心粉很滑,需要两把叉子才能夹住。哲学家的生活中有两种交替活动时段,吃饭(EATING)和思考(THINKING)。当一个哲学家觉得饿了时,他就试图分两次去取左手边和右手边的叉子,每次拿一把,但不分次序。如果成功拿到两把叉子,就进入吃饭状态,吃完后放下叉子继续思考。 二、设计思路 1.每个哲学家的行为活动状态为两种:进餐(EATING)和思考(THINKING)。因此创建一个有5个元素的状态数组,每个数组元素的状态值为EATING或者THINKING。 2.五个哲学家围坐成一圈,每两个人中间有一个叉子,即每个哲学家的边和右边有一个叉子,但这个叉子需要和旁边的邻居竞争使用。对于每一个哲学家来说,其只有成功获得两个叉子,才能进入进餐状态。在进完餐后,需要成功放下手中的两个叉子,才能进入思考的状态。换个角度的描述就是,每个哲学家查询左右边的邻居当前状态,如果左右的邻居当前状态都为THINKING,则该哲学家可以进餐;如果左右邻居当前状态不都是THINKING,则哲学家不能进餐。因此可以为每一个哲学家设置一个信号量,来描述哲学家的活动状态。 3.因为五只叉子做多只能允许两个哲学家进餐,所以可以将桌子作为一个临界资源。通过设置一个互斥信号量来限制对临界资源的访问数。 4.创建两个动作函数,对应于每个哲学家的获取两把叉子和放下两把叉子的动作。而每个动作都需要对互斥信号量和哲学家信号量进行访问操作,因此创建原子操作P和原子操作V,来执行对信号量的消耗和释放操作。 5.利用父进程创建五个子进程来模拟五个哲学家,在每个子进程中执行PHILOSOPHER (phi_num)函数来模拟每个哲学家进入哲学家进餐问题活动。 三、主要问题的解决方法和关键技术 1.共享状态数组问题。 问题描述:因为状态数组是共享的,而每个模拟哲学家的子进程是相互独立的,有自己的地址空间,在进程之间共享使用状态数组出现问题。 解决方法:父进程通过利用UNIX系统进程通信机制中共享内存机制的shmget()和shmat系统调用创建一个共享内存区,并将状态数组地址链接到进程地址空间,成功的解决了该问题。 2.信号量创建及初始化问题 问题描述:整个程序使用两个不同的信号量,一个是记录型信号量数组,一个是互斥

相关主题
文本预览
相关文档 最新文档