进程同步问题的研究与模拟.docx
- 文档编号:29374159
- 上传时间:2023-07-22
- 格式:DOCX
- 页数:41
- 大小:1,002.62KB
进程同步问题的研究与模拟.docx
《进程同步问题的研究与模拟.docx》由会员分享,可在线阅读,更多相关《进程同步问题的研究与模拟.docx(41页珍藏版)》请在冰豆网上搜索。
进程同步问题的研究与模拟
广东
商学院
2011-JX16-
本科毕业论文(设计)
进程同步问题的研究与模拟
院(系)
专业
学号
学生姓名
指导教师
提交日期
2011年5月15日
诚 信 声 明
本人郑重声明:
所呈交的毕业论文(设计)是我个人在导师指导下,由我本人独立完成。
有关观点、方法、数据和文献等的引用已在文中特别指出,并与参考文献相对应。
据我查证,除了文中特别加以标注外,论文中不包括其他已经发表和撰写的研究成果,也不包括为获得其他教育机构的学位或证书而使用过的材料。
我承诺,论文中的所有内容均真实、可信。
如在文中涉及到抄袭或剽窃行为,本人愿承担由此而造成的一切后果及责任。
毕业论文(设计)作者签名:
2011 年 5 月 14 日
毕业论文(设计)成绩评定表
毕业论文(设计)指导教师评语及成绩
论文选题符合专业培养目标,能够达到综合训练目标,完整地实现了进程同步问题的模型,对于Linux内核通信的运行原理作了详细的说明,理论联系实际,具有一定的学术价值。
文章篇幅符合学院规定,内容较为完整,论述紧扣主题,主要观点突出,逻辑关系清楚。
语言表达流畅,格式符合要求,参考了较多的书籍,其理论性较强。
文章达到本专业学士学位水平,同意参加答辩。
成绩指导教师签名
年月日
毕业论文(设计)复评教师评语及成绩
成绩复评教师签名
年月日
毕业论文(设计)答辩评语及成绩
成绩答辩委员会主席签名
年月日
毕业论文(设计)总成绩(五级记分制)
院(系)负责人签名
年月日
TITLE:
Processsynchronizationproblemsresearchandsimulation
MAJOR:
ImformationManagementandImformationSystem
APPLICANT:
YanZhenjiang
SUPERVISOR:
GaoWenyu
内容摘要
在多道程序环境下,计算机系统中存在着多个进程,这提高了资源的利用率和系统的吞吐量,但由于进程的异步性,也会给系统造成混乱,尤其是在他们争用临界资源时。
因此,如何保证多个程序协调运行是一个重要的研究热点。
而进程间同步由于其内核通信机制的复杂性成为程序设计的研究难点。
基于此,本文提出了一个基于Linux内核通信机制的、支持程序突发中断的生产者消费者模型。
该模型使用信号量进行进程同步,通过共享内存进行进程间通信,使用信号来处理中断,实现了多个程序在系统中的同步与通信功能。
关键词:
进程同步通信互斥
Abstract
Inthemultiprogrammingenvironment,thecomputersystemtherearemultipleprocesses,whichincreasesresourceutilizationandsystemthroughput,butbecauseoftheasynchronousnatureoftheprocesswillcauseconfusiontothesystem,especiallycriticalintheircontentionresources.Therefore,howtoensurecoordinatedoperationofmultipleprogramsisanimportantresearchfocus.Theinter-processcommunicationmechanismssimultaneouslybecauseofitscomplexityofkernelprogrammingofadifficulty.Basedonthis,weproposeacommunicationmechanismbasedontheLinuxkerneltosupporttheprocessmodelofsuddeninterruptionoftheproducersandconsumers.Themodelusessemaphoresforprocesssynchronizationbysharedmemoryforinterprocesscommunication,interrupthandlingusingthesignalstoachieveanumberofprogramsinthesystemofsynchronizationandcommunicationfunctions.
Keywords:
Processsynchronouscommunicationmutex
目录
1引言1
1.1背景1
1.2研究的目的与意义1
1.3同步与互斥1
1.4linux操作系统与c语言2
2Linux同步通信原理5
2.1问题概述5
2.2模型目标5
2.3原理与接口6
3问题定义15
3.1进程同步15
3.2进程通信15
3.3原语15
4同步问题实现17
4.1程序头文件17
4.2函数定义17
4.3主程序的设计19
5程序测试26
5.1只有一个生产者一个消费者的情况26
5.2多个生产者多个消费者的情况29
6结束语36
参考文献37
致谢
1引言
1.1背景
在多道程序环境下,计算机系统中存在着多个进程,这些进程间并非相互隔绝。
一方面他们相互协作以达到运行用户运行用户作业所预期的目的。
为了完成一项任务,在两个或多个进程进行合作时,必定会发生数据共享,另一方面他们又互相竞争有限的资源。
这两个要素都意味着进程之间需要某种形式来进行同步与互斥。
在OS中引入进程后,虽然提高了资源的利用率和系统的吞吐量,但由于进程的异步性,也会给系统造成混乱,尤其是在他们争用临界资源时。
因此,良好的进程同步与互斥机制在程序设计时显得特别重要。
1.2研究的目的与意义
在多道程序系统中,程序的执行失去了封闭性和再现性,程序的运行具有不确定性,这是我们所不希望看到的。
如果多道程序系统中程序的执行不加控制,程序的每次执行就可能得到不同的结果。
如何使多道程序的执行的结果具有再现性和确定性?
这就需要通过进程间的同步和互斥来实现,将原来无序的、不确定的程序的执行转换为有序的、确定的执行。
1.3同步与互斥
1.3.1进程的同步
进程的同步是指进程之间一种直接的协同工作关系,一些进程相互协作,共同完成一项任务。
进程之间的同步也是进程间的一种直接制约关系,一个进程的执行依赖另一个进程的消息,当一个进程执行到某一点时,必须得到加一个进程发来的消息,在没有得到另一个进程的消息时该进程应该等待,直到消息到达才被唤醒,继续进程的执行。
1.3.2进程的互斥
在系统中,许多进程常常需要共享资源,而这些资源往往要求排他性地使用,即一次只能为一个进程服务,因此,各进程间只能互斥使用这些资源,进程间的这种关系就是进程的互斥。
1.3.3临界区
要做到能够互斥的使用共享资源就引入了临界资源和临界区的概念。
若在系统中的某些资源一次只允许一个进程使用,则这类资源称为临界资源,临界区就是每个进程中访问临界资源的那一段程序。
保证在某一时刻只有一个进程能访问数据的简便办法。
在任意时刻只允许一个进程对共享资源进行访问。
如果有多个进程试图同时访问临界区,那么在有一个进程进入后其他所有试图访问此临界区的进程将被挂起,并一直持续到进入临界区的进程离开。
临界区在被释放后,其他进程可以继续抢占,并以此达到用原子方式操作共享资源的目的。
解决同步和互斥问题最常用的方法就是信号量的方法,通过在程序中使用P、V操作达到同步和互斥的目的。
1.4Linux操作系统与c语言
1.4.1Linux简介
Linux是当前最流行的操作系统之一。
它是由芬兰大学生Linus开发的类Unix操作系统,它具有系统内核小、稳定性高、可扩展性好、对硬件要求低、网络功能强等特点,现在已经成为成熟的操作系统,并以其良好的稳定性和优异的性能给用户带来了全新的感受,赢得了人们的普遍青睐。
Linux系统的主要构成:
(1)存储管理
在Linux中,每一个进程都有一个比实际物理空间大得多的进程虚拟空间,每个进程还保留一张页表,用于将本进程空间中的虚地址变换成物理地址,页表还对物理页的访问权限作了规定,从而达到存储保护的目的。
(2)进程管理
在Linux中,进程是资源分配的基本单位,所有资源都是以进程为对象进行分配的,在一个进程的生命周期中,会用到许多系统资源,Linux的设计可以准确描述进程的状态和资源的使用情况,以确保不出现某些进程过度占用系统资源而导致另一些进程无休止地等待的情况。
(3)文件系统
Linux最重要的特征之一就是支持多种不同的文件系统。
在Linux中,一个分离的文件系统不是通过设备标志来访问,而是把它合到一个单一的目录树结构中去,通过目录访问。
Linux把一个新的文件系统安装到系统单一目录树的某一目录下,则该目录下的所有内容被新安装的文件系统所覆盖,当文件系统被卸下后,安装目录下的文件将会被重新恢复。
1.4.2进程间通信
Linux下进程间通信的几种主要方法(主要使用了SystemVIPC接口):
(1)管道(Pipe)及有名管道(namedpipe)
管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
(2)信号(Signal)
信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
(3)消息队列
消息队列是消息的链接表,有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
(4)共享内存
共享内存使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(5)信号量
信号量主要作为进程间以及同一进程不同进程之间的同步手段。
套接口(Socket):
更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:
Linux和SystemV的变种都支持套接字。
共享内存是进程通信中是最有效和速度最快的方法之一,进程可以直接读写内存,结合信号量进行同步,可以解决大部分进程同步的问题。
本文采用共享内存结合信号量来模拟生产者消费者问题。
1.4.3C语言
C语言原是AT&T属下的BellLabs的DennisRitchie为开发UNIX操作系统而独立设计并实现的。
随着UNIX操作系统的广泛流行及微型计算机的普及推广,C语言作为Unix操作系统的孪生兄弟,也广泛地应用于软件开发领域[2]。
它的简洁、高效、可移植性等众多优点受到软件开发人员的喜爱,成为最受欢迎的编程语言。
1.4.4GCC编译器
在Linux开发环境下,gcc是进行程序开发不可或缺的编译工具,是GUNCCompile的缩写,它是在GUN系统下的标准C编译器[1]。
gcc作为Linux平台下的标准C编译器,功能强大。
人们可以使用gcc编译器编译单一文件的最基本的命令,正是有了gcc编译器人们才能使用它编译C源程序。
2Linux同步通信原理
2.1问题概述
生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。
,两个进程共享一个公共的固定大小的缓冲区。
其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。
问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。
同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
在同一时刻只有一个进程能够访问缓冲区。
2.2模型目标
2.2.1生产者消费者之间的同步
多个生产/消费者在有界缓冲上操作。
它利用N个字节的共享内存作为有界循环缓冲区,利用写一字符模拟放一个产品,利用读一字符模拟消费一个产品。
当缓冲区空时消费者应阻塞睡眠,而当缓冲区满时生产者应当阻塞睡眠。
一旦缓冲区中有空单者元,生产进程就向空单元中写入字符,并报告写的内容和位置,同时唤醒睡眠的消费者。
一旦缓冲区中有未读过的字符,消费者进程就从该单元中读出字符,并报告读取位置,同时唤醒睡眠的生产者。
生产者不能向同一单元中连续写两次以上相同的字符,消费者也不能从同一单元中连续读两次以上相同的字符。
2.2.2程序的中断处理
当生产者生产完时,将唤醒等待消费的消费者。
当消费者消费完时,将唤醒等待生产的生产者。
为保证进程间的正确同步,当生产者在生产时不可以被中断,必须生产完唤醒消费者后才可以中断退出。
当消费者在消费时也不可以被中断,必须消费完唤醒生产者后才可以中断退出。
因此必须设计中断处理模块,保证程序在关键区域的执行是原子操作。
2.2.3程序的可再现性
当程序重复运行时,不论它是从头到尾不停顿地执行,还是"停停走走"地执行,都将获得相同的结果。
SystemVIPC是随内核持续的,例如即使所有访问共享内存的进程都已经正常终止,共享内存区仍然存在(除非显式删除共享内存),在内核重新引导之前,对该共享内存区域的任何改写操作都将一直保留。
为了保证程序的可再现性,必须设计终止处理模块供程序终止之后调用。
2.3原理与接口
本论文主要使用了信号,信号量集,共享内存[3],因此着重介绍这几方面。
2.3.1关键字和描述符key
SYSTEMV信号量是SYSTEMVIPC(即SYSTEMV进程间通信)的组成部分,其他的有SYSTEMV消息队列,SYSTEMV共享内存。
而关键字和IPC描述符无疑是它们的共同点,要使用它们,就不得不先对它们进行熟悉。
这里只对SYSTEMV信号量进行讨论。
IPC描述符相当于引用ID号,要想使用SYSTEMV信号量(或MSG、SHM),就必须用IPC描述符来调用信号量。
而IPC描述符是内核动态提供的(通过semget来获取),用户无法让服务器和客户事先认可共同使用哪个描述符,所以有时候就需要到关键字KEY来定位描述符。
某个KEY只会固定对应一个描述符(这项转换工作由内核完成),这样假如服务器和客户事先认可共同使用某个KEY,那么大家就都能定位到同一个描述符,也就能定位到同一个信号量,这样就达到了SYSTEMV信号量在进程间共享的目的。
2.3.2信号
(1)信号本质
中断处理是操作系统和系统软件的关键部分,Unix下的软件中断被称为信号,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。
信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
信号通常发生于以下3种情况:
当用户按下终端驱动程序分配给信号控制字符的任何按键时,内核会向相应进程发送信号。
例如我们常常通过输入Ctrl+C来终止前台进程,此时,就是由内核向该进程发送SIGINT信号,而这个信号的默认处理动作是终止进程[4]。
当一个进程在执行中发生错误时,内核会向该进程发送相应的信号。
例如,非法段存取、浮点数溢出,或是一个非法的机器指令。
内核也利用信号通知进程特定事件的发生。
一个进程可以通过系统调用kill给另一个进程发送信号,因此,信号可以作为进程间通信的一种方式。
(2)信号处理
进程在收到信号以后,接受用户自定义的默认动作。
进程可以事先注册信号处理函数,当接收到信号时,由信号处理函数自动捕捉并且处理信号。
(3)设置信号处理动作
信号定义函数:
intsigaction(intsigno,conststructsigaction*act,structsigaction*oact);
第一个参数signo指定需要处理的特定信号,应该在signo类型信号收到之前就调用sigaction;第二个参数act设定signo信号的处理动作,在结构体sigaction中定义;第三个参数oact返回的是此信号的当前设置值。
act和oact的值都可能是NULL。
头文件
程序1信号处理结构体
structsigaction
{
void(*sa_handler)(int);
sigset_tsa_mask;
intsa_flags;
void(*s_sigaction)(int,siginfo_t*,void*);
};
(4)信号处理函数
void(*sa_handler)(int);
sa_handler指定接收到信号signo后的处理函数。
当进程接收到信号signo时,就会以signo为参数执行这个函数。
也就是说,当进程
收到signo信号时,不管它在执行什么程序,控制立即转向sigaction所设的处理函数。
当该函数返回时,控制返回到进程中断的位置。
(5)信号处理过程
程序在运行时设置了信号处理函数,开始捕捉信号。
当用户按下中断键(如CTRL+C)时,触发信号处理动作,开始执行处理函数,函数执行后返回,从中断处继续执行。
具体过程如图2.1所示。
图2.1信号处理图
2.3.3信号量及PV操作原语
(1)信号量原理
信号量的思想最是由计算机理论学家E.W.Dijkstra在解决进程同步问题时提出的[5],主要提供对进程间共享资源访问控制机制,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。
除了用于访问控制外,还可用于进程同步。
信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。
信号量在使用过程中它的值是可变的,但只能由P,V操作来改变。
(2)Dijkstra同时提出了对信号量操作的PV原语。
P原语操作的动作是:
1.S减1;
2.若S减1后仍大于或等于零,则进程继续执行;
3.若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
1.S加1;
2.若相加结果大于零,则进程继续执行;
3.若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
PV操作对于每一个进程来说,必须成对使用。
互斥信号量mutex的初值一般为1。
在PV原语执行期间不允许有中断的发生[6]。
2.3.4SystemV信号量API
SystemV信号量实现为信号量的集合,而不是单个的信号量,相关的信号量操作函数由
内核为每个信号量集维护一个信号量结构体,可在
程序2信号量结构体
structsemid_ds{
structipc_permsem_perm;/*信号量集的操作许可权限*/
structsem*sem_base;/*某个信号量sem结构数组的指针*/
ushortsem_nsems;/*sem_base数组的个数*/
time_tsem_otime;/*最后一次成功修改信号量数组的时间*/
time_tsem_ctime;/*成功创建时间*/
};
(1)创建和打开信号量
intsemget(key_tkey,intnsems,intoflag);
semget函数执行成功后,就产生了一个由内核维持的类型为semid_ds结构体的信号量集,返回semid就是指向该信号量集的引索,semop和semctl函数将使用它。
(2)设置信号量的值(PV操作):
intsemop(intsemid,structsembuf*sops,unsignednsops);
semid是信号量集ID,sops指向数组的每一个sembuf结构都刻画一个在特定信号量上的操作。
nsops为sops指向数组的大小。
sembuf结构如程序3所示。
程序3信号量设置结构体
structsembuf{
unsignedshortsem_num;/*信号量集中的索引*/
shortsem_op;/*信号操作*/
shortsem_flg;/*操作标记*/
};
信号量的当前值记录相应资源目前可用数目;sem_op>0对应相应进程要释放sem_op数目的共享资源;sem_op=0可以用于对共享资源是否已用完的测试;sem_op<0相当于进程要申请-sem_op个共享资源。
(3)对信号量集实行控制操作:
intsemctl(intsemid,intsemnum,intcmd,unionsemunarg);
该系统调用实现对信号量的各种控制操作,参数semid指定信号量集,参数cmd指定具体的操作类型;参数semnum指定对哪个信号量操作,只对几个特殊的cmd操作有意义;arg用于设置或返回信号量信息。
cmd为IPC_STAT时,获取信号量信息,信息由arg.buf返回。
cmd为SETVAL时,设置semnum所代表信号量的值为arg.val。
unionsemun是系统调用semctl中的重要参数,具体定义如程序4所示。
程序4信号量操作结构体
unionsemun{
intval;/*信号量的值*/
structsemid_ds*buf;/*IPC状态结构体*/
unsignedshort*array;
structseminfo*__buf;/*IPC信息结构体*/
};
系统中使用一个结构体来记录权限,该结构是所有IPC机制共有的,用来记录系统中IPC的各种访问权限。
结构体的定义如程序5所示。
程序5IPC权限结构体
structipc_perm{
uid_tuid;
gid_tgid;
uid_tcuid;
gid_tcgid;
modt_tmode;
ulongseq;
key_tkey;
};
2.3.5共享内存
(1)共享内存在内核中的表示:
共享内存区域是被多个进程共享的一部分物理内存。
如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 同步 问题 研究 模拟