操作系统实验报告生产者与消费者问题模拟
操作系统生产者与消费者问题实验报告

《操作系统》实验报告生产者和消费者的问题一、实验目的1.掌握基本的同步与互斥的算法,理解基本的生产者与消费者的模型。
2.学习使用Windows 2000/XP中基本的同步对象,掌握相关的API的使用方法。
3.了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。
二、实验的内容及其要求1.实验内容以生产者/消费者模型为根据,在Windows 2000环境下创建一个控制台进程,在改进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求①学习并理解生产者/消费者模型及其同步/互斥规则②学习了解Windows同步对象及其特性③熟悉实验环境,掌握相关API的使用方法④设计程序,实现生产者/消费者进程(线程)的同步与互斥⑤提交实验报告三、实验的时间安排1.实验前,先到图书馆或上网百度了解有关生产者/消费者模型的相关知识,建立生产者/消费者模型的基本概念。
2.利用13周、15周、17周的上机时间编写和调试程序代码。
3.利用其他课余时间来分析实验的最终结果并完成相关的实验报告。
四、实验的环境1.硬件条件:普通计算机一台2.软件条件:①操作系统:Windows 2000/XP②开发语言:VC++本实验是在Windows 2000+VC6.0环境下实现的,利用Windows SDK提供的系统接口(API)完成程序的功能。
实验在Windows 下安装VC后进行,因为VC是一个集成开发环境,其中包含了Windows SDK所有工具和定义,所以安装了VC后就不用特意安装SDK了。
实验中所用的API(应用程序接口),是操作系统提供的用来进行应用程序设计的系统功能接口。
要使用这些API,需要包含对这些函数进行说明的SDK头文件,最常见的就是windows.h。
一些特殊的API调用还需要包含其他的头文件。
五、正文1.程序结构图:2.数据结构:(1)用一个整型数组Buffer_Critical来代表缓冲区。
操作系统实验报告生产者消费者问题

操作系统课程设计一.实验目标完成N个生产者和M个消费者线程之间的并发控制,N、M不低于30,数据发送和接收缓冲区尺寸不小于20个(每个产品占据一个)。
其中生产者线程1、3、5、7、9生产的产品供所有奇数编号的消费者线程消费,只有所有奇数编号的消费者线程都消费后,该产品才能从缓冲区中撤销。
其中生产者线程2、4、6、8、10生产的产品所有偶数编号的消费者线程都可消费,任一偶数编号消费者线程消费该消息后,该产品都可从缓冲区中撤销。
其中11-20号生产者线程生产的产品仅供对应编号的消费者线程消费。
其他编号生产者线程生产的产品可由任意的消费者线程消费。
每个生产线程生产30个消息后结束运行。
如果一个消费者线程没有对应的生产者线程在运行后,也结束运行。
所有生产者都停止生产后,如果消费者线程已经没有可供消费的产品,则也退出运行。
二.实验原理2.1原理生产者与消费者线程采用posix互斥锁机制进行互斥进入各自的代码段,只有采用互斥锁临界区代码段才可以不被打扰的执行;同步机制采用的是posix条件变量pthread_cond_wait和pthraed_cond_signal进行同步的。
线程间的通信采用的是共享内存机制。
(注:所有的共享内存块是在进程里建立的,线程只需链接上各自的共享内存块即可,每一块共享内存的大小是100). 在这里共享内存设置成一个100的数组。
具体实施:(1)为1.3.5.7.9建立一个共享内存1号,1.3.5.7.9生产者线程生产的产品都放入这块共享内存缓冲区,所有奇数的消费者线程要消费的话,只需在消费者线程中链接上这块共享内存,就可以直接消费1.3.5.7.9生产者线程生产的产品。
(2)为2.4.6.8.10建立一块共享内存2号。
2.4.6.8.10生产的产品都放入2号共享内存缓冲区,所有的偶数的消费者线程只要链接上2号缓冲区,就可以消费2.4.6.8.10生产的产品。
当偶数消费者线程消费产品后,产品即可从缓冲区撤销,方法是在消费线程里将消费的产品在共享内存数组里置0。
操作系统实验报告生产者消费者问题

课程设计说明书山东科技大学2014年 1 月 1 日课程设计任务书一、课程设计题目:生产者消费者问题二、课程设计主要参考资料(1)《计算机操作系统》(修订版).汤子瀛.西安电子科技大学出版社。
(2)《数据结构》严蔚敏清华大学出版社(3)《操作系统概念》第六版三、课程设计应解决的主要问题:(1)了解信号量的使用(2)理解生产者消费者问题模型(3)掌握真确使用同步机制的方法(4)实现生产者消费者进程的互斥与同步四、课程设计相关附件(如:图纸、软件等):程序源代码五、任务发出日期: 2013-12-1 课程设计完成日期: 2014-12-25指导教师签字:系主任签字:指导教师对课程设计的评语成绩:指导教师签字:年月日生产者消费者问题一、设计目的1、了解信号量的使用2、加深对信号量机制的理解3、通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制.4、掌握基本的同步互斥算法,理解生产者与消费者模型5、了解多线程(多进程)的并发执行机制,线程(进程)间的同步与互斥二、设计要求1、理解生产者与消费者问题模型,掌握解决问题的算法思想2、掌握正确使用同步机制的方法3、每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.4、生产者和消费者各有两个以上.5、多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码.三、设计说明(含系统框图和(或)主要算法的流程图)生产者流程图消费者流程图有n个生产者和m个消费者,连接在具有k个单位缓冲区的有界环转缓冲上,故又称有界缓冲问题。
其中Pi 和Cj都是并发进程,只要缓冲区未满,生产者进程Pi所生产的产品就可投入缓冲区;类似地,只要缓冲区非空,消费者进程Cj就可以从缓冲区取走并消耗产品。
生产者——消费者问题是典型的进程同步问题,这些进程必须按照一定的生产率和消费率来访问共享缓冲区,用P、V操作解决生产者和消费者共享单缓冲区的问题,可设置两个信号量empty和full,其初值分别为1和0,empty指示能否向缓冲区放入产品,full 指示能否从缓冲区取出产品。
操作系统实验报告

实验一(生产者—消费者)一.实验题目生产者与消费者实验二.实验目的加深进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,掌握相关的API的使用,了解多线程的并发执行机制,实现线程的同步与互斥的基本方法。
三.实验容分析已编制的一个“生产者—消费者”实例,并将缺失的代码补充完整,然后调试这段程序,得出最终的结果,并分析此结果,得出相应的结论,尝试改变一些参数,分析这一改变对结果的影响。
四.设计思路和算法1.利用windows提供的API函数CreateSemaphore()创建信号量对象;Create Thread()创建线程;WaitForSingleObject()执行P操作;Release Semaphore()执行V操作;WaitForMultipleObjects()主进程等待线程的结束等函数进行设计。
2.在Windows中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex) 。
使用这些对象都分为三个步骤,一是创建或者初始化;接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。
这些同步对象在主进程中创建,在其子线程中都可五.主要数据结构每个进程有一个进程控制块( PCB)表示。
进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。
系统开辟了一个缓冲区,大小由buffersize指定。
程序中有三个链队列,一个链表。
一个就绪队列(ready),两个等待队列:生产者等待队列(producer);消费者队列(consumer)。
一个链表(over),用于收集已经运行结束的进程本程序通过函数模拟信号量的原子操作。
六.程序运行结果运行程序后的结果:生产者1准备生产生产者1开始往缓冲区中写数据生产者1开始退出缓冲区...生产者2准备生产生产者2开始往缓冲区中写数据生产者2开始退出缓冲区...消费者1准备消费消费者1开始消费缓冲区中数据消费者1开始退出缓冲区...生产者3准备生产生产者3开始往缓冲区中写数据生产者3开始退出缓冲区...消费者2准备消费消费者2开始消费缓冲区中数据消费者2开始退出缓冲区...生产者4准备生产生产者4开始往缓冲区中写数据生产者4开始退出缓冲区...消费者3准备消费消费者3开始消费缓冲区中数据消费者3开始退出缓冲区...生产者5准备生产生产者5开始往缓冲区中写数据生产者5开始退出缓冲区...消费者4准备消费消费者4开始消费缓冲区中数据消费者4开始退出缓冲区...生产者6准备生产生产者6开始往缓冲区中写数据生产者6开始退出缓冲区...消费者5准备消费消费者5开始消费缓冲区中数据消费者5开始退出缓冲区...生产者7准备生产生产者7开始往缓冲区中写数据生产者7开始退出缓冲区...消费者6准备消费消费者6开始消费缓冲区中数据消费者6开始退出缓冲区...生产者8准备生产生产者8开始往缓冲区中写数据生产者8开始退出缓冲区...消费者7准备消费消费者7开始消费缓冲区中数据消费者7开始退出缓冲区...生产者9准备生产生产者9开始往缓冲区中写数据生产者9开始退出缓冲区...消费者8准备消费消费者8开始消费缓冲区中数据消费者8开始退出缓冲区...生产者10准备生产生产者10开始往缓冲区中写数据生产者10开始退出缓冲区...消费者9准备消费消费者9开始消费缓冲区中数据消费者9开始退出缓冲区...消费者10准备消费消费者10开始消费缓冲区中数据消费者10开始退出缓冲区...七.源程序#include<windows.h>#include<fstream.h>#include<stdio.h>#include<string>#include<conio.h>#define MAX_BUFFER_NUM 10#define INTE_PER_SEC 1000#define MAX_THREAD_NUM 64strict ThreadInfo{into serial;char entity;double delay;into thread_request[MAX_THREAD_NUM];into n_request;};CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];into Buffer_Critical[MAX_BUFFER_NUM]; HANDLE h_Thread[MAX_THREAD_NUM]; ThreadInfo Thread_Info[MAX_THREAD_NUM]; HANDLE empty_semaphore;HANDLE h_mutex;DWORD n_Thread = 0;DWORD n_Buffer_or_Critical;HANDLE h_Semaphore[MAX_THREAD_NUM];void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(into);into FindProducePositon();into FindBufferPosition(into);into main(void){DWORD wait_for_all;ifstream inFile;for(into i=0;i< MAX_BUFFER_NUM;i++) Buffer_Critical[i] = -1;for(into j=0;j<MAX_THREAD_NUM;j++){ for(into k=0;k<MAX_THREAD_NUM;k++) Thread_Info[j].thread_request[k] = -1;Thread_Info[j].n_request = 0;}for(i =0;i< MAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]); inFile.open("test.txt");inFile >> n_Buffer_or_Critical;inFile.get();printf("输入文件是:\n");printf("%d \n",(into) n_Buffer_or_Critical);while(inFile){inFile >> Thread_Info[n_Thread].serial;inFile >> Thread_Info[n_Thread].entity;inFile >> Thread_Info[n_Thread].delay;char c;inFile.get(c);while(c!='\n'&& !inFile.eof()){inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_reque st++];inFile.get(c);}n_Thread++;}for(j=0;j<(into) n_Thread;j++){into Temp_serial = Thread_Info[j].serial;char Temp_entity = Thread_Info[j].entity;double Temp_delay = Thread_Info[j].delay;printf(" \n 线程:%2d %c %f ",Temp_serial,Temp_entity,Temp_delay);into Temp_request = Thread_Info[j].n_request;for(into k=0;k<Temp_request;k++)printf(" %d ", Thread_Info[j].thread_request[k]);cout<<endl;}printf("\n\n");empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critical,n_ Buffer_or_Critical,"semaphore_for_empty");h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update");for(j=0;j<(into)n_Thread;j++){std::string lp ="semaphore_for_produce_";into temp =j;while(temp){char c = (char)(temp%10);lp+=c;temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp.c_str());}for(i =0;i< (into) n_Thread;i++){if(Thread_Info[i].entity =='P')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )(Consume),&(Thread_Info[i]),0,NULL);}wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf(" \n \n所有生产和消费已经完成他们的工作。
操作系统之进程(生产者---消费者)实验报告

操作系统实验报告——生产者和消费者问题姓名:学号:班级:一、实验内容1、模拟操作系统中进程同步和互斥;2、实现生产者和消费者问题的算法实现;二、实验目的1、熟悉临界资源、信号量及PV操作的定义与物理意义;2、了解进程通信的方法;3、掌握进程互斥与进程同步的相关知识;4、掌握用信号量机制解决进程之间的同步与互斥问题;5、实现生产者-消费者问题,深刻理解进程同步问题;三、实验题目在Windows操作系统下用C语言实现经典同步问题:生产者—消费者,具体要求如下:(1)一个大小为10的缓冲区,初始状态为空。
(2)2个生产者,随机等待一段时间,往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据之后再添加,重复10次。
页脚内容1(3)2个消费者,随机等待一段时间,从缓冲区中读取数据,若缓冲区为空,等待生产者添加数据之后再读取,重复10次。
四、思想本实验的主要目的是模拟操作系统中进程同步和互斥。
在系统进程并发执行异步推进的过程中,由于资源共享和进程间合作而造成进程间相互制约。
进程间的相互制约有两种不同的方式。
(1)间接制约。
这是由于多个进程共享同一资源(如CPU、共享输入/输出设备)而引起的,即共享资源的多个进程因系统协调使用资源而相互制约。
(2)直接制约。
只是由于进程合作中各个进程为完成同一任务而造成的,即并发进程各自的执行结果互为对方的执行条件,从而限制各个进程的执行速度。
生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。
生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。
在本实验中,进程之间要进行通信来操作同一缓冲区。
生产者消费者问题实验报告

操作系统课程设计实验报告实验名称: 生产者消费者问题姓名/学号:一、实验目的以生产者和消费者问题为例, 学习Linux和Windows下进程通信、同步机制的具体实现方法, 主要是信号量和共享内存。
熟悉相关系统API的用法。
二、实验内容使用共享内存和信号量机制来实现多个生产者/消费者进程间的通信和同步。
要求在Linux和Windows下分别实现。
缓冲区大小为3, 初始为空。
2个生产者, 随机等待一段时间, 往缓冲区添加数据, 重复6次。
3个消费者, 重复4次。
三、实验环境Ubuntu 10.10 , GCC; Windows 7, VC 6.0;四、程序设计与实现1.Linux下:(1) 数据结构:a.共享内存定义为一个结构, 使得其数据成员更清晰且操作变得简单。
b.共享缓冲区采用循环队列的数据结构,由上面的结构struct buf { int start; int end; int info[BUF_NUM]; }维护。
其中start为队头指针, end为队尾指针, info为数据区域。
(2) 算法:a.大致由三个模块组成:i.主程序(main):ii.创建信号量、共享内存并进行初始化iii.创建生产者、消费者进程, 生产者执行pro_fun(), 消费者执行con_fun()iv.等待所有子进程的结束v.删除信号量、共享内存i.生产者进程(pro_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(empty), P(mutex), Add(data), V(mutex), V(full)iv.解除和共享内存的关联i.消费者进程(con_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(full), P(mutex), Add(data), V(mutex), V(empty)iv.解除和共享内存的关联循环队列部分:加入数据: info[end] = value; end = (end + 1) % 3;取出数据: temp = info[start]; info[start] = 0; (start = start + 1)%3; return temp;(3) 程序流程图:a.主函数:b.生产者进程:c.消费者进程和生产者类似4.Windows 下:(1) 数据结构:和Linux大致相同(2) 算法:a.创建的子进程调用正在执行的文件本身, 通过main函数的参数区分主进程和生产者、消费者进程。
操作系统_生产者与消费者问题的实现

//shmctl(shmid,IPC_RMID,&buf);
//del_sem(semid);
return 0;
}
/*生产者写5次后退出*/
void producer(key_t keyFull, key_t keyEmpty)
empty Write P1 : 2
empty Write P2 : 4
in = 0
Write : 5
full Write V1 : 0
full Write V2 : 0
full Read P2 : 0
out = 0
Read : 5
empty Read V1 : 4
empty Read V2 : 5
Write : 7
full Write V1 : 0
full Write V2 : 0
full Read P2 : 0
out = 2
Read : 7
empty Read V1 : 4
empty Read V2 : 5
Read Finish
p(empty); /*是否有空缓冲区,有则占有,无则被挂起,是原子操作*/
printf("empty Write P2 : %d\n", semctl(empty, 0, GETVAL, 0));
value_write++;
in = in++;
pData[in] = value_write;
in = in % 5;
printf("full Write V2 : %d\n", semctl(full, 0, GETVAL, 0));
计算机操作系统实验-生产者和消费者

重庆交通大学综合性设计性实验报告班级:软件专业 2010 级一班姓名:李佳奇实验项目名称:生产者与消费者实验项目性质:操作系统多任务实验所属课程:计算机操作系统实验室(中心):语音大楼 8 楼 801指导教师:米波实验完成时间: 2012 年 11 月 23 日一、实验目的1、通过实验来模拟生产者与消费者,来深入了解什么事操作系统的进程,以及进程有些什么特性。
2、了解进程间是如何做到同步的,进程间是如何做到通信的。
3、通过实验来了解进程之间同步和通信机制。
二、实验内容及要求做一个能够能直观地体现多个进程之间通过临界区进行数据的访问修改,体现出生产者和消费者关系,通过信号量进行控制。
三、实验设备PC机,windows7,eclipse。
四、设计方案㈠设计主要思想(1).要模拟多线程并发,则首先需要可视化地体现进程的运行,这样我们才能看到效果,所以可以通过进度条的长度表示生产者的生产过程和消费者的消费过程,而临界缓冲区则定义一个自定义的栈。
(2).分别定义一个生产者和两个消费者,这三个进程是完全独立的,生产者不断的向缓冲区放货物,当缓冲区满了的时候,则阻塞自己,直到消费者取走了一个货物后,将通知生产者将其唤醒。
(3).消费者不断的从缓冲区里取数据,当缓冲区为空时,则阻塞自己,直到生产者将一个货物放到缓冲区时,通知消费者,将消费着唤醒,消费者重新开始消费。
㈡设计的主要步骤(1).创建一个自定义的栈类StackBuffer,在压栈和出栈时实现同步互斥,在压栈的时候先判断堆栈是否已满,若满,则使压栈线程阻塞,否则压栈。
在出栈的时候先判断是否栈为空,若空,则将出栈线程阻塞。
核心代码:public synchronized void push(JLabel product){while(isFull()){try{this.wait();} catch (InterruptedException e){e.printStackTrace();}}this.notifyAll();productbuffer[sip++].setVisible(true);}public synchronized JLabel pop(){while(isEmpty()){try{this.wait();} catch (InterruptedException e){e.printStackTrace();}}this.notifyAll();productbuffer[--sip].setVisible(false);return productbuffer[sip];}(2).创建一个customer类继承JProgressBar类,接口Runnable,并且拥有一个StackBuffer类,在run()方法中实现在不断向StackBuffer类对象中出栈。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统上机实验报告
实验名称:
生产者与消费者问题模拟
实验目的:
通过模拟生产者消费者问题理解进程或线程之间的同步与互斥。
实验内容:
1、设计一个环形缓冲区,大小为10,生产者依次向其中写入1到20,每个缓冲区中存放一个数字,消费者从中依次读取数字。
2、相应的信号量;
3、生产者和消费者可按如下两种方式之一设计;
(1)设计成两个进程;
(2)设计成一个进程内的两个线程。
4、根据实验结果理解信号量的工作原理,进程或线程的同步\互斥关系。
实验步骤及分析:
一.管道
(一)管道定义
所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。
(二)所涉及的系统调用
1、pipe( )
建立一无名管道。
系统调用格式
pipe(filedes)
参数定义
int pipe(filedes);
int filedes[2];
其中,filedes[1]是写入端,filedes[0]是读出端。
该函数使用头文件如下:
#include <unistd.h>
#inlcude <signal.h>
#include <stdio.h>
2、read( )
:
系统调用格式
read(fd,buf,nbyte)
功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf 所指示的缓冲区中。
如该文件被加锁,等待,直到锁打开为止。
参数定义:
int read(fd,buf,nbyte);
int fd;
char *buf;
unsigned nbyte;
3、write( )
系统调用格式
read(fd,buf,nbyte)
功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。
如文件加锁,暂停写入,直至开锁。
参数定义同read( )。
(三)参考程序
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int pid1,pid2;
main( )
{
int fd[2];
char outpipe[100],inpipe[100];
pipe(fd); /*创建一个管道*/
while ((pid1=fork( ))==-1);
if(pid1==0)
{
lockf(fd[1],1,0);
/*把串放入数组outpipe中*/
sprintf(outpipe,child 1 is using pipe!);
/* 向管道写长为50字节的串*/
write(fd[1],outpipe,50);
sleep(5); /*自我阻塞5秒*/
lockf(fd[1],0,0);
exit(0);
}
else
{
while((pid2=fork( ))==-1);
if(pid2==0)
{
lockf(fd[1],1,0); /*互斥*/
sprintf(outpipe,child 2 is using pipe!);
write(fd[1],outpipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
wait(0); /*同步 */
read(fd[0],inpipe,50);/*从管道中读长为 50字节的串*/
printf(%s\n,inpipe);
wait(0);
read(fd[0],inpipe,50);
printf(%s\n,inpipe);
exit(0);
}
}
}
编写过程:
运行结果:
二、信号机制
(一)信号的基本概念
每个信号都对应一个正整数常量(称为signal number,即信号编号。
定义在系统头文件<signal.h>中),代表同一用户的诸进程之间传送事先约定的信息的类型,用于通知某进程发生了某异常事件。
每个进程在运行时,都要通过信号机制来检查是否有信号到达。
若有,便中断正在执行的程序,转向与该信号相对应的处理程序,以完成对该事件的处理;处理结束后再返回到原来的断点继续执行。
实质上,信号机制是对中断机制的一种模拟,故在早期的UNIX 版本中又把它称为软中断。
.
(二)所涉及的中断调用
1、kill( )
系统调用格式
int kill(pid,sig)
参数定义
int pid,sig;
其中,pid是一个或一组进程的标识符,参数sig是要发送的软中断信号。
(1)pid>0时,核心将信号发送给进程pid。
(2)pid=0时,核心将信号发送给与发送进程同组的所有进程。
(3)pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。
2、signal( )
预置对信号的处理方式,允许调用进程控制软中断信号。
系统调用格式
signal(sig,function)
头文件为
#include <signal.h>
参数定义
signal(sig,function)
int sig;
void (*func) ( )
function:在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGKILL,SIGTRAP和SIGPWR以外的信号,核心自动地重新设置软中断信号处理程序的值为SIG_DFL,一个进程不能捕获SIGKILL信号。
(三)参考程序
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void waiting( ),stop( );
int wait_mark;
main( )
{
int p1, p2;
int stdout1;
while((p1=fork( ))==-1); /*创建子进程p1*/
f (p1>0)
i
{
while((p2=fork( ))==-1); /*创建子进程p2*/
if(p2>0)
{
wait_mark=1;
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(stdout1,1,0);
printf(Child process 2 is killed by parent!\n);
lockf(stdout1,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(16,stop); /*接收到软中断信号16,转stop*/ waiting( );
lockf(stdout1,1,0);
printf(Child process 1 is killed by parent!\n);
lockf(stdout1,0,0);
exit(0);
}}
void waiting( )
{
while(wait_mark!=0);
}
void stop( )
{
wait_mark=0;
}
编译过程:
运行结果:。