实验四 经典的进程同步问题

合集下载

经典进程同步问题

经典进程同步问题
19
一、利用记录型信号量
解决哲学家进餐问题
假设每一位哲学家拿筷子的方法都是:先 拿起左边的筷子,再拿起右边的筷子,则第i 位哲学家的活动可描述为:
20
第i位哲学家的活动可描述为: repeat wait(chopstick[i]); wait(chopstick[i+1] mod 5); …. eat; …. signal(chopstick[i]); signal(chopstick[i+1] mod 5); …. think; until false;
full:=full - 1; if full <0 then block; mutex:=mutex-1; if mutex<0 then block; mutex:=mutex+1; if mutex<=0 then wakeup; empty:=empty+1; if empty<=0 then wakeup;
9
Wait操作不能颠倒!! P:wait(empty) wait(mutex)
C:wait(full) wait(mutex)
如果颠倒 P:wait(mutex) mutexl.value=0 wait(empty) 如果此时缓冲池满empty=-1,P阻塞 C:wait(mutex) mutex.value=-1, C阻塞 wait(full) P阻塞在empty队列中,等待一个空缓冲 C阻塞在mutex队列中,等待公共缓冲池访问权
6
consumer://消费者进程 begin repeat wait(full); wait(mutex); nextc:=buffer[out]; out∶=(out+1) mod n; signal(mutex); signal(empty); 消费这件产品; until false; end

操作系统实验四 进程的同步

操作系统实验四 进程的同步

操作系统实验报告哈尔滨工程大学软件学院第六讲进程的同步一、实验概述1. 实验名称实验系统的启动2. 实验目的1).使用EOS 的信号量编程解决生产者—消费者问题,理解进程同步的意义。

2).调试跟踪EOS 的信号量的工作过程,理解进程同步的原理。

3).修改EOS 的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

3. 实验类型(验证、设计)验证4. 实验内容1).准备实验2).使用EOS的信号量解决生产者-消费者问题3).调试EOS信号量的工作过程①创建信号量②等待释放信号量③等待信号量(不阻塞)④释放信号量(不唤醒)⑤等待信号量(阻塞)⑥释放信号量(唤醒)4).修改EOS的信号量算法在目前EOS Kernel项目的ps/semaphore.c文件中,PsWaitForSemaphore 函数的Milliseconds参数只能是INFINITE,PsReleaseSemaphore 函数的ReleaseCount 参数只能是1。

现在要求同时修改PsWaitForSemaphore函数和PsReleaseSemaphore函数中的代码,使这两个参数能够真正起到作用,使信号量对象支持等待超时唤醒功能和批量释放功能。

二、实验环境操作系统:windows xp编译环境:OS Lab三、实验过程1. 设计思路和流程图图3-1.整体试验流程图图3-2.Main 函数流程图、生产者消费、消费者流程图2. 需要解决的问题及解答(1).思考在ps/semaphore.c文件内的PsWaitForSemaphore和PsReleaseSemaphore函数中,为什么要使用原子操作?答:在执行等待信号量和释放信号量的时候,是不允许cpu响应外部中断的,如果此时cpu响应了外部中断,会产生不可预料的结果,无法正常完成原子操作。

(2). 绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore 函数的流程图。

进程同步——经典的同步问题

进程同步——经典的同步问题

进程同步——经典的同步问题本⽂为博主原创⽂章,未经博主允许不得转载涉及进程同步的⼀些概念:互斥与同步:临界资源(临界区):指⼀次只能允许⼀个进程使⽤的共享资源称为临界资源;同步:指为完成某种任务⽽建⽴的两个和多个进程,这些进程在合作的过程中需要协调⼯作次序进⾏有序的访问⽽出现等待所产⽣的制约关系。

互斥:指两个或多个进程访问临界资源时只能⼀个进程访问,其他进程等待的⼀种相互制约的关系。

信号量与互斥量:信号量:本⾝是⼀个计数器,使⽤P,V两个操作来实现计数的减与加,当计数不⼤于0时,则进程进⼊睡眠状态,它⽤于为多个进程提供共享数据对象的访问。

互斥量:如果信号量只存在两个状态,那就不需要计数了,可以简化为加锁与解锁两个功能,这就是互斥量。

⼀、⽣产者与消费者问题问题描述:⼀组⽣产者进程和⼀组消费者进程共享⼀块初始为空,⼤⼩确定的缓冲区,只有当缓冲区为满时,⽣产者进程才可以把信息放⼊缓冲区,否则就要等待;只有缓存区不为空时,消费者进程才能从中取出消息,否则就要等待。

缓冲区⼀次只能⼀个进程访问(临界资源)。

问题分析:⽣产者与消费者进程对缓冲区的访问是互斥关系,⽽⽣产者与消费者本⾝⼜存在同步关系,即必须⽣成之后才能消费。

因⽽对于缓冲区的访问设置⼀个互斥量,再设置两个信号量⼀个记录空闲缓冲区单元,⼀个记录满缓冲区单元来实现⽣产者与消费者的同步。

问题解决:伪代码实现semaphore mutex=1;semaphore full=0; //满缓冲区单元semaphore empty=N; //空闲缓冲区单元prodecer(){while(1){P(empty);P(mutex);add_source++;V(mutex);V(full);}}consumer(){while(1){P(full);P(mutex);add_source--;V(mutex);V(empty);}}⼆、读者与写者问题问题描述:有读者与写者两个并发进程共享⼀个数据,两个或以上的读进程可以访问数据,但是⼀个写者进程访问数据与其他进程都互斥。

os10-实验四-经典的进程同步问题

os10-实验四-经典的进程同步问题

六、有关的系统功能调用: signal(int sig,int function)//;预置对信号的处理方式
int sig:信号 void (*function) ( ) 接收到指定信号后的处理函数
参数sig
值 名 字 说 明
01
02 03 04
SIGHUP
SIGINT SIGQUIT SIGILL
signal(SIGINT,stop); /*接收到^c信号,转stop*/ waiting( ); kill(p1,16); /*向p1发软中断信号16*/ kill(p2,17); /*向p2发软中断信号17*/ wait(0); /*同步*/ wait(0); printf("Parent process is killed!\n"); exit(0); } else { wait_mark=1; signal(17,stop); /*接收到软中断信号17,转stop*/ waiting( ); lockf(stdout,1,0); printf("Child process 2 is killed by parent!\n"); lockf(stdout,0,0); exit(0); } }
挂起(hangup)
中断,当用户从键盘按^c键或^break键时 退出,当用户从键盘按quit键时 非法指令
05
06 07 08 09 10 11 12 13
SIGTRAP
SIGIOT SIGEMT SIGFPE SIGKILL SIGBUS SIGSEGV SIGSYS SIGPIPE
跟踪陷阱(trace trap),启动进程,跟踪代码的执行
IOT指令 EMT指令 浮点运算溢出 杀死、终止进程 总线错误 段违例(segmentation violation),进程试图去访问其虚地址空间以外的位置 系统调用中参数错,如系统调用号非法 向某个非读管道中写入数据

操作系统实验四 进程的同步

操作系统实验四 进程的同步

操作系统实验报告哈尔滨工程大学软件学院.第六讲进程的同步一、实验概述1. 实验名称实验系统的启动2. 实验目的1).使用EOS 的信号量编程解决生产者—消费者问题,理解进程同步的意义。

2).调试跟踪EOS 的信号量的工作过程,理解进程同步的原理。

3).修改EOS 的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

3. 实验类型(验证、设计)验证4. 实验内容1).准备实验2).使用EOS的信号量解决生产者-消费者问题3).调试EOS信号量的工作过程①创建信号量②等待释放信号量③等待信号量(不阻塞)④释放信号量(不唤醒)⑤等待信号量(阻塞)⑥释放信号量(唤醒)4).修改EOS的信号量算法在目前EOS Kernel项目的ps/semaphore.c文件中,PsWaitForSemaphore函数的Milliseconds参数只能是INFINITE,PsReleaseSemaphore 函数的ReleaseCount 参数只能是1。

现在要求同时修改PsWaitForSemaphore函数和PsReleaseSemaphore 函数中的代码,使这两个参数能够真正起到作用,使信号量对象支持等待超时唤醒功能和批量释放功能。

二、实验环境操作系统:windows xp编译环境:OS Lab1三、实验过程1. 设计思路和流程图准备实验的信号量解决EOS使用整体试验流程图图3-1. 2函数开始ConsumerProducer函数开始函数开始mainProd对象Mutex创建ucer生产完Consumer费消数函毕?函数结束毕完结束信号Empty创建量对信号量对释Empty3-2.Main图函数流程图、生产者消费、消费者流程图32. 需要解决的问题及解答(1).思考在ps/semaphore.c文件内的PsWaitForSemaphore和PsReleaseSemaphore 函数中,为什么要使用原子操作?答:在执行等待信号量和释放信号量的时候,是不允许cpu响应外部中断的,如果此时cpu响应了外部中断,会产生不可预料的结果,无法正常完成原子操作。

实验四同步与互斥Linux实验报告

实验四同步与互斥Linux实验报告

实验四同步与互斥【实验目的和要求】1、掌握进程(线程)的同步与互斥。

2、掌握生产者消费者问题的实现方法。

3、掌握多线程编程方法。

【实验内容】实现生产者消费者问题1、有一个仓库,生产者负责生产产品,并放入仓库,消费者会从仓库中拿走产品(消费)。

2、仓库中每次只能入一个(生产者或消费者)。

3、仓库中可存放产品的数量最多10个,当仓库放满时,生产者不能再放入产品。

4、当仓库空时,消费者不能从中取出产品。

5、生产、消费速度不同。

【实验原理】1、信号量mutex提供对缓冲池访问的互斥要求并初始化为1,信号量empty和full分别用来表示空缓冲项和满缓冲项的个数,信号量empty初始化为n,信号量full初始化为0。

2、定义如下结构及数据:定义缓冲区内的数据类型:typedef int buffer_item;缓冲区:buffer_item buffer[BUFFER_SIZE];对缓冲区操作的变量:int in,out;信号量mutex提供了对缓冲池访问的互斥要求:pthread_mutex_t mutex;信号量empty和full分别表示空缓冲顶和满缓冲顶的个数:sem_t empty,full; 可以设定生产者的生产速度及消费者的消费速度:int pro_speed,con_speed;对缓冲区操作的自增函数:#define inc(k) if(k < BUFFER_SIZE) k = k+1;else k=03、并定义了如下实现问题的函数模块:将生产的产品放入缓冲区: int insert_item(buffer_item item)从缓冲区内移走一个产品: int remove_item(buffer_item *item)生产者进程:void *producer(void *param)消费者进程:void *consumer(void *param)生产者结构进程消费者结构进程【程序代码】//sx.c#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<semaphore.h>#include<time.h>#define inc(k) if(k<BUFFER_SIZE) k=k+1;else k=0#define BUFFER_SIZE 10//缓冲区的大小typedef int buffer_item;//定义缓冲区内的数据类型buffer_item buffer[BUFFER_SIZE];//缓冲区int in,out;//对缓冲区操作的变量pthread_mutex_t mutex;//信号量mutex提供了对缓冲池访问的互斥要求sem_t empty,full;//信号量empty和full分别表示空缓冲顶和满缓冲顶的个数int pro_speed,con_speed;//可以设定生产者的生产速度及消费者的消费速度int insert_item(buffer_item item){//将生产的产品放入缓冲区buffer[in]=item;printf("******insert缓冲池第%d号******\n",in);inc(in);}int remove_item(buffer_item *item){//从缓冲区内移走一个产品*item = buffer[out];printf("******remove缓冲池第%d号******\n",out);inc(out);}void *producer(void *param){//生产者进程buffer_item item;int num = 0;while(1){sleep(rand()%(16-pro_speed));printf("\n******第%d次生产******\n",++num);printf("******等待empty信号******\n");sem_wait(&empty);printf("******等待解锁******\n");pthread_mutex_lock(&mutex);printf("******上锁,准备生产******\n");item = rand()%1000+1;printf("******生产产品%d*******\n",item);insert_item(item);printf("*******解锁******\n");printf("******第%d次生产结束*******\n\n",num); pthread_mutex_unlock(&mutex);sem_post(&full);}}void *consumer(void *param){//消费者进程buffer_item item;int num = 0;while(1){sleep(rand()%(16-con_speed));printf("\n******第%d次消费*****\n",++num); printf("******等待full信号******\n");sem_wait(&full);printf("******等待解锁******\n");pthread_mutex_lock(&mutex);printf("******上锁,准备消费******\n"); remove_item(&item);pthread_mutex_unlock(&mutex);sem_post(&empty);printf("******消费产品%d*******\n",item);printf("*******解锁******\n");printf("******第%d次消费结束*******\n\n",num); }}int main()//主函数{pthread_t tid1,tid2;pthread_attr_t attr1,attr2;srand(time(NULL));pthread_mutex_init(&mutex,NULL);//初始化sem_init(&empty,0,BUFFER_SIZE);sem_init(&full,0,0);in=0;out=0;printf("***********************\n");printf("********开始!***********\n");printf("***********************\n");printf("生产者速度(1-15):\n");scanf("%d",&pro_speed);printf("消费者速度(1-15):\n");scanf("%d",&con_speed);pthread_attr_init(&attr1);pthread_create(&tid1,&attr1,producer,NULL);pthread_attr_init(&attr2);pthread_create(&tid2,&attr2,consumer,NULL);sleep(100);printf("*******程序over*******\n");return 0;}【实验步骤】编写程序代码gedit sx.c,再对代码进行编译gcc sx.c –o sx –lpthread,编译无错误,进行运行./sx,根据提示要求进行填写生产者和消费速度,观察消费者和生产者进程。

实验四 进程的同步

实验四 进程的同步

实验四进程的同步一、实验目的●使用EOS的信号量编程解决生产者—消费者问题,理解进程同步的意义。

●调试跟踪EOS的信号量的工作过程,理解进程同步的原理。

●修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

二、预备知识2.1 临界资源和临界区多个并发执行的进程可以同时访问的硬件资源(打印机、磁带机)和软件资源(共享内存)都是临界资源。

由于进程的异步性,当它们争用临界资源时,会给系统造成混乱,所以必须互斥地对它们进行访问。

我们把在每个进程中访问临界资源的那段代码称为临界区(Critical Section),可以使用互斥体(Mutex)保证各进程互斥地进入自己的临界区可以看到进入临界区和退出临界区一定是成对出现的。

2.2 进程的同步进程同步的主要任务是使并发执行的各进程之间能有效的共享资源和相互合作。

可以使用互斥体(Mutex)、事件(Event)和信号量(Semophore)等同步对象来解决一系列经典的进程同步问题,例如“生产者-消费者问题”、“读者-写者问题”、“哲学家进餐问题”等。

2.3 生产者-消费者问题生产者-消费者问题是一个著名的进程同步问题。

它描述的是:有一群生产者进程在生产某种产品,并将此产品提供给一群消费者进程去消费。

为使生产者进程和消费者进程能并发执行,在他们之间设置了一个具有n个缓冲区的缓冲池,生产者进程可以将它生产的一个产品放入一个缓冲区中,消费者进程可以从一个缓冲区中取得一个产品消费。

尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已经装有产品的缓冲区中放入产品。

2.4 EOS内核提供的用于线程同步的内核对象EOS内核提供了三种专门用于线程同步的内核对象,分别是互斥(Mutex)对象、信号量(Semaphore)对象和事件(Event)对象。

另外,EOS中的进程对象和线程对象也支持同步功能。

山东大学操作系统实验报告4进程同步实验

山东大学操作系统实验报告4进程同步实验

计算机科学与技术学院实验报告int msq_id;if((msq_id = get_ipc_id("/proc/sysvipc/msg",msq_h)) < 0 ) { if((msq_id = msgget(msq_h,msq_flg)) < 0){perror("messageQueue set error");exit(EXIT_FAILURE);}}return msq_id;}实验结果:分析:多进程的系统中避免不了进程间的相互关系。

进程互斥是进程之间发生的一种间接性作用,一般是程序不希望的。

通常的情况是两个或两个以上的进程需要同时访问某个共享变量。

我们一般将发生能够问共享变量的程序段称为临界区。

两个进程不能同时进入临界区,否则就会导致数据的不一致,产生与时间有关的错误。

解决互斥问题应该满足互斥和公平两个原则,即任意时刻只能允许一个进程处于同一共享变量的临界区,而且不能让任一进程无限期地等待。

进程同步是进程之间直接的相互作用,是合作进程间有意识的行为,典型的例子是公共汽车上司机与售票员的合作。

只有当售票员关门之后司机才能启动车辆,只有司机停车之后售票员才能开车门。

司机和售票员的行动需要一定的协调。

同样地,两个进程之间有时也有这样的依赖关系,因此我们也要有一定的同步机制保证它们的执行次序。

信号量机制就是其中的一种。

信号灯机制即利用pv操作来对信号量进行处理。

PV操作由P操作原语和V 操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减1,即S=S-1;②如果S³0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。

V(S):①将信号量S的值加1,即S=S+1;②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

void waiting( ) { while(wait_mark!=0); } void stop( ) { wait_mark=0; }
八、思考题
1、lockf(stdout,1,0)的作用是什么? 2、该程序段前面部分用了两个wait(0),它们起什么作用? 3、该程序段中每个进程退出时都用了语句exit(0),为什么? 4、为何预期的结果并未显示出? 5、程序该如何修改才能得到正确结果?
else { wait_mark=1; signal(16,stop); /*接收到软中断信号16,转stop*/ waiting( ); lockf(stdout,1,0); printf("Child process 1 is killed by parent!\n"); lockf(stdout,0,0); exit(0); } }
闹钟。当某进程希望在某时间后接收信号时发此信号
软件终止(software termination) 用户自定义信号1 用户自定义信号2 某个子进程死 电源故障
七、参考代码
#include <stdio.h> #include <signal.h> #include <unistd.h> void waiting( ),stop( ); int wait_mark; main( ) { int p1,p2,stdout; while((p1=fork( ))= =-1); /*创建子进程p1*/ if (p1>0) { while((p2=fork( ))= =-1); /*创建子进程p2*/ if(p2>0) { wait_mark=1;
六、有关的系统功能调用: signal(int sig,int function)//;预置对信号的处理方式
int sig:信号 void (*function) ( ) 接收到指定信号后的处理函数
参数sig
值 名 字 说 明
01
02 03 04
SIGHUP
SIGINT SIGQUIT SIGILL
)、
signal( )的功能及用能否得到
结果?为什么?尝试修改源代码,得到预期的结果。 3. 写实验报告
六、有关的系统功能调用: int kill(pid_t pid, int sig); //向进程组或进程发送信号 pid: 1. pid大于零,pid是信号欲送往的进程的标识。 2.pid等于零,信号将送往所有与调用kill()的那个进程属同 一个使用组的进程。 3. pid等于-1,信号将送往所有调用进程有权给其发送信号 的进程,除了进程1(init)。 4. pid小于-1时,信号将送往以-pid为组标识的进程。 sig:准备发送的信号,其值为零则没有任何信号送出
signal(SIGINT,stop); /*接收到^c信号,转stop*/ waiting( ); kill(p1,16); /*向p1发软中断信号16*/ kill(p2,17); /*向p2发软中断信号17*/ wait(0); /*同步*/ wait(0); printf("Parent process is killed!\n"); exit(0); } else { wait_mark=1; signal(17,stop); /*接收到软中断信号17,转stop*/ waiting( ); lockf(stdout,1,0); printf("Child process 2 is killed by parent!\n"); lockf(stdout,0,0); exit(0); } }
Child process1 is killed by parent!
Child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed!
实 验 四
• 五、实验要求
1. 阅读有关的参考书,学习系统功能调用 kill(
挂起(hangup)
中断,当用户从键盘按^c键或^break键时 退出,当用户从键盘按quit键时 非法指令
05
06 07 08 09 10 11 12 13
SIGTRAP
SIGIOT SIGEMT SIGFPE SIGKILL SIGBUS SIGSEGV SIGSYS SIGPIPE
跟踪陷阱(trace trap),启动进程,跟踪代码的执行
实 验 四
• 一、编程实现生产者—消费者问题
• 二、进程间的通信 • 三、实验目的 • 1. 掌握进程同步的实现算法
(软中断信号)
• 1. 了解什么是信号 • 2. 熟悉LINUX系统中进程之间软中断通信的基本原 理
实 验
四、实验任务

1. 编写程序,创建生产者和消费者进程,生产者进程产生数据并写入缓冲区,消费 者进程取数据并输出,缓冲区能存放四个数据,如果缓冲区满,则生产者不能写 数据,并报警;如果缓冲区空,消费者不能取数据,并报警。(选做,2个生产者, 2个消费者) 2. 编写程序:用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘 上来的中断信号(即按^c键);捕捉到中断信号后,父进程用系统调用kill( )向两 个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
IOT指令 EMT指令 浮点运算溢出 杀死、终止进程 总线错误 段违例(segmentation violation),进程试图去访问其虚地址空间以外的位置 系统调用中参数错,如系统调用号非法 向某个非读管道中写入数据
14
15 16 17 18 19
SIGALRM
SIGTERM SIGUSR1 SIGUSR2 SIGCLD SIGPWR
相关文档
最新文档