南昌大学操作系统实验报告二编程模拟进程间的同步和互斥
进程(线程)同步和互斥实验报告
进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2021一、实验题目: : 进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容、组织的变化,理解进程与其 PCB 间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。
3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解 Windows 同步对象及其特性;熟悉实验环境,掌握相关 API 的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h> #include <iostream> #include<stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;#define MA__THREAD_NUM 64//最大线程数 #define INTE_PER_SEC 1000//延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10;//缓冲区长度 int ProductID = 0;//产品号 int ConsumeID = 0;//将被消耗的产品号 int in = 0;//产品进缓冲区时的缓冲区下标 int out = 0;//产品出缓冲区时的缓冲区下标 bool running = true;//判断程序能否继续执行的逻辑值 intg_buffer[SIZE_OF_BUFFER];//缓冲区是个循环队列 HANDLE g_hMute_;//公有信号量,用于线程间的互斥 HANDLEg_hFullSemaphore;//生产者的私有信号量,当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore;//消费者的私有信号量,当缓冲区空时迫使消费者等待//定义一个结构体用于存储线程的信息 struct ThreadInfo {int serial;//线程号char entity;//线程类别(生产者或消费者)double delay;//等待时间double persist; //操作时间 };//生产者 void Producer(void_p) {//定义变量用于存储当前线程的信息DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “生产者线程” << m_serial << “ 请求生产.” << endl;WaitForSingleObject(g_hEmptySemaphore, INFINITE);cout << “生产者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_, INFINITE);Sleep(m_delay);//延迟等待//生产一个产品cout << “生产者线程”<< m_serial << “ 生产” << ++ProductID << “ 号产品成功.” << endl;cout << “生产者线程” << m_serial << “ 请求将产品” << ProductID << “ 投入缓冲区.” << endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in +1)%SIZE_OF_BUFFER;Sleep(m_persist);//操作等待cout << “生产者线程” << m_serial << “ 将产品” << ProductID << “ 投入缓冲区中成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图(■代表已有产品,□代表没有产品):” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hFullSemaphore, 1, NULL);} }//消费者 void Consumer(void_p) {DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “消费者线程” << m_serial << “ 请求消费.” << endl;WaitForSingleObject(g_hFullSemaphore, INFINITE);cout << “消费者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout << “消费者线程” << m_serial << “ 请求取出一个产品.” << endl;ConsumeID = g_buffer[out];g_buffer[out] = 0;out = (out + 1) % SIZE_OF_BUFFER;cout << “消费者线程” << m_serial << “ 取出产品” << ConsumeID << “ 成功.” << endl;//消耗一个产品cout << “消费者线程” << m_serial << “ 开始消费消费产品” << ConsumeID << “.” << endl;Sleep(m_persist);cout << “消费者线程” << m_serial << “ 消费产品” << ConsumeID << “ 成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图:” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);} }void prod_cons {//创建互斥信号量g_hMute_ = CreateMute_(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0,SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL));//以时间函数为种子const unsigned short THREADS_COUNT = rand % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MA__THREAD_NUM];ThreadInfo thread_info[MA__THREAD_NUM];DWORD thread_ID; //线程 IDint num = 0;//临时变量,用于循环语句cout << “系统开始模拟,并自动生成模拟数据...” << endl;system(“pause”); //暂停确认开始执行cout << “线程总数:” << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand % 2 == 1)thread_info[num].entity = "P";elsethread_info[num].entity = "C";thread_info[num].delay = rand % 5 + 1;thread_info[num].persist = rand % 6 + 2;num++;}cout << “\n 系统生成数据结束,模拟数据如下:” << endl<< “线程号线程类别延迟时间操作时间” << endl;for (int _ = 0;_ < THREADS_COUNT;_++)cout << “” << thread_info[_].serial << “\t”<< “” << thread_info[_].entity << “\t”<< “” << thread_info[_].delay << “\t\t”<< “” << thread_info[_].persist << endl;cout << “\n\n==================生产者-消费者开始==================\n” << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == "P")hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), ;thread_info[i], 0, ;thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), ;thread_info[i], 0, ;thread_ID);}while (running){if (getchar){//按回车后终止程序运行running = false;}}cout << “系统模拟结束...” << endl; } int main {cout << “\n==================生产者-消费者模拟==================\n” << endl;prod_cons; }五、实验过程1、记录生产者和消费者的同步执行过程。
进程的同步与互斥实验报告
进程的同步与互斥实验报告1.实验目的进程(线程)的同步与互斥是操作系统中非常重要的概念,本实验旨在通过实际操作,加深对这些概念的理解和掌握。
通过编写多个进程(线程),并在其间进行同步与互斥操作,验证同步与互斥的实际效果。
2.实验环境本实验在Linux系统下进行,使用C/C++语言编程。
3.实验内容3.1同步在实验中,我们编写了两个进程A和B,这两个进程需要按照特定的顺序执行。
为了实现同步,我们使用信号量机制来确保进程A和B按照正确的顺序执行。
3.2互斥在实验中,我们编写了多个进程C和D,这些进程需要同时对一个共享资源进行访问。
为了实现互斥,我们使用互斥锁机制来确保同一时刻只有一个进程访问共享资源。
4.实验过程4.1同步实验编写进程A和进程B的代码,使用信号量机制实现同步。
进程A先运行,然后通过信号量唤醒进程B,进程B再开始执行。
通过观察进程的运行顺序,验证同步机制是否起作用。
4.2互斥实验编写进程C和进程D的代码,使用互斥锁机制实现互斥。
进程C和进程D同时对一个共享资源进行访问,通过互斥锁来确保同一时刻只有一个进程访问共享资源。
观察进程的输出结果,验证互斥机制是否起作用。
5.实验结果5.1同步实验结果进程A开始执行进程A执行完毕进程B开始执行进程B执行完毕5.2互斥实验结果进程C开始执行进程C访问共享资源进程C执行完毕进程D开始执行进程D访问共享资源进程D执行完毕6.实验分析通过上述结果可以看出,同步实验中进程A和进程B按照正确的顺序执行,证明了同步机制的有效性。
互斥实验中进程C和进程D能够正确地交替访问共享资源,证明了互斥机制的有效性。
7.实验总结通过本次实验,我深刻理解了进程(线程)的同步与互斥,并通过实际操作加深了对这些概念的理解。
同步和互斥是操作系统中非常重要的概念,对于应对资源竞争和提高程序性能具有重要意义。
在实际开发中,我们应该合理使用同步和互斥机制,以确保程序的正确性和并发执行的效率。
南昌大学操作系统实验报告二编程模拟进程间的同步和互斥
南昌大学实验报告---(2)编程模拟进程间的同步与互斥学生姓名: 张皓然学号: 5501215001 专业班级: 本硕151实验类型:□验证□综合■设计□创新实验日期: 2017、5、5 实验成绩:一、实验目的通过实验加强对进程同步与互斥的理解,并掌握进程(线程)的创建与调用方法。
学会使用信号量解决资源共享问题。
学生可以自己选择在Windows或Linux系统下编写。
二、实验内容(一)以下为Linux系统下参考程序,请编译、运行并观察程序的输出,并分析实验结果,写出实验报告。
#include<stdio、h>//标准输入输出头文件#include<stdlib、h>//standard library标准库头文件#include<unistd、h>//POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX 系统服务的函数原型,例如read函数、write函数与getpid函数。
#include<time、h>//time、h就是C标准库头文件,主要就是一些与时间相关的函数#include<sys/types、h>//基本系统数据类型#include<sys/wait、h>//declarations for waiting#include<linux/sem、h>//Semaphore operation flags#define NUM_PROCS 5//5个子进程#define SEM_ID 250//信号量#define "/tmp/sem_aaa"#define DELAY 4000000void update_ sem_set_id, char *, int number){struct sembuf sem_op;FILE *建立一个文件指针//等待信号量的数值变为非负数,此处设为负值,相当于对信号量进行P操作sem_op、sem_num=0;sem_op、sem_op=-1;sem_op、sem_flg=0;semop(sem_set_id,&sem_op,1);/*操作一组信号,进程的标识符号为sem_set_id,sem_op就是结构指针。
实验二 编程实现进程(线程)同步和互斥
《操作系统》实验内容实验二编程实现进程(线程)同步和互斥1.实验的目的(1)通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。
(2)了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。
(3)学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。
(4)掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。
(5)掌握多道程序设计的基本理论、方法和技术,培养学生多道程序设计的能力。
2.实验内容在Windows XP、Windows 2000等操作系统下,使用的VC、VB、java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者-消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
3.实验要求(1)经调试后程序能够正常运行。
(2)采用多进程或多线程方式运行,体现了进程(线程)同步和互斥的关系。
(3)程序界面美观。
4.实验步骤(1)需求分析:了解基本原理,确定程序的基本功能,查找相关资料,画出基本的数据流图;(2)概要设计:确定程序的总体结构、模块关系和总体流程;(3)详细设计:确定模块内部的流程和实现算法;(4)上机编码和调试;(5)运行测试;(6)编写实验报告。
5.实验报告要求格式符合《实验报告格式》书;书写规范,排版美观,有较强的文字表达能力,能够正确地表达自己的思想,图表符合规范。
6.实验说明本实验分两次进行,每次要求填写一份实验报告,报告中的实验名分别为:编程实现进程同步和互斥1和编程实现进程同步和互斥2,其他内容依据实验进度具体填写。
2.实验:进程的同步和互斥
《操作系统实验》
实验一:进程的同步和互斥
黄伯虎
实验内容
生产者消费者问题实现
描述:
假设存在两类进程:生产者,消费者。
它们共享n个缓冲区。
生产者行为:生产产品(每次生产1个),并将产品放入空缓冲区,循环往复,永不停息;
消费者行为:将产品从缓冲区中取出,进行消费(每次消费1个),循环往复,永不停息。
规定:缓冲区满,生产者不能放产品;缓冲区空,消费者不能取产品
要求
基本要求
实现当n=1,生产者、消费者各为1个时,同步和互斥过程
扩展要求(可选)
实现当n=c(整常数),生产者、消费者有多个(>1)时,同步和互斥过程平台和工具(原则不限,推荐如下)
Win32平台
VC++6.0
结果显示
字符界面,能说明问题即可
最终成果形式
提交实验报告1份(格式参见附件A)
报告提交时限:下一次实验开始前
提交形式:email
提交的邮件主题请按照如下格式书写:“学号+姓名+实验名称.rar/.doc”
如“030811300+张三+进程同步与互斥.rar/.doc”提交地址:
13班:xdos1@
14,31班:xdos2@。
操作系统实验报告——进程同步与互斥
操作系统实验报告——进程同步与互斥一、实验内容本实验主要内容是通过编写程序来实现进程的同步与互斥。
具体来说,是通过使用信号量来实现不同进程之间的同步和互斥。
我们将编写两个进程,一个进程负责打印奇数,另一个进程负责打印偶数,两个进程交替打印,要求打印的数字从1开始,直到100结束。
二、实验原理进程的同步是指多个进程之间按照一定的顺序执行,进程之间互相等待的关系。
而进程的互斥是指多个进程竞争同一个资源,需要通过其中一种方式来避免同时访问共享资源,以免造成数据错乱。
在本实验中,我们使用信号量来实现进程的同步与互斥。
信号量是一个计数器,用于表示一些共享资源的可用数量。
进程在访问共享资源时,需要先对信号量进行操作,当信号量大于0时,表示资源可用,进程可以访问;当信号量等于0时,表示资源不可用,进程需要等待。
进程同步的实现可以通过信号量的P操作与V操作来完成。
P操作用于申请资源,当资源可用时,将计数器减一,并进入临界区;V操作用于释放资源,当资源使用完毕时,将计数器加一,使等待资源的进程能够申请。
进程互斥的实现可以通过信号量的P操作与V操作结合临界区来完成。
当多个进程需要访问共享资源时,需要先进行P操作,进入临界区,访问完毕后进行V操作,离开临界区。
三、实验步骤1.首先,我们需要创建两个进程,一个进程负责打印奇数,另一个进程负责打印偶数。
2. 然后,我们创建一个共享变量count,用来记录打印的数字。
3. 接着,我们创建两个信号量odd和even,用来控制进程的同步与互斥。
odd信号量初始值为1,表示打印奇数的进程可以访问;even信号量初始值为0,表示打印偶数的进程需要等待。
4.编写奇数打印进程的代码,首先进行P操作,判断奇数信号量是否大于0,如果大于0,表示可以打印奇数。
5. 如果可以打印奇数,将count加一,并输出当前的奇数,然后进行V操作,释放偶数打印进程的等待。
6.同样的,编写偶数打印进程的代码,首先进行P操作,判断偶数信号量是否大于0,如果大于0,表示可以打印偶数。
进程的同步实验报告
进程的同步实验报告进程的同步实验报告引言:进程同步是操作系统中一个重要的概念,它涉及到多个进程之间的协调和合作。
在本次实验中,我们将通过一个简单的实例来探讨进程同步的概念和实现方式。
实验目的:通过实验,我们的目标是理解进程同步的概念,学习常见的同步机制,并通过编程实现一个简单的同步问题。
实验环境:本次实验使用了C语言作为编程语言,并在Linux操作系统上进行。
实验过程:我们的实验场景是一个餐厅,有一个厨师和多个服务员。
厨师负责烹饪菜品,服务员负责上菜给客人。
我们需要实现的是,服务员只有在厨师烹饪好一道菜之后才能上菜,否则需要等待。
首先,我们使用互斥锁来实现进程间的同步。
互斥锁是一种常见的同步机制,它可以确保在同一时间只有一个进程可以访问共享资源。
在我们的实验中,厨师和服务员都需要访问菜品资源,因此我们为菜品资源添加了一个互斥锁。
接下来,我们使用条件变量来实现进程间的等待和唤醒操作。
条件变量是一种同步机制,它可以让进程在某个条件满足时等待,直到被唤醒。
在我们的实验中,服务员需要等待厨师烹饪好菜品之后才能上菜,因此我们创建了一个条件变量,并在服务员的代码中使用了等待和唤醒操作。
实验结果:经过实验,我们成功地实现了进程间的同步。
在我们的实验场景中,厨师会不断地烹饪菜品,并在烹饪完成后通知服务员上菜。
服务员会等待厨师的通知,然后上菜给客人。
通过互斥锁和条件变量的使用,我们保证了服务员只会在厨师烹饪完成后才会上菜,避免了资源竞争和错误的上菜行为。
讨论与总结:通过本次实验,我们深入理解了进程同步的概念和实现方式。
互斥锁和条件变量是常见的同步机制,它们可以有效地解决进程间的竞争和协调问题。
在实际的操作系统中,进程同步是一个非常重要的概念,它保证了多个进程之间的正确执行和合作。
然而,进程同步也可能引发一些问题。
例如,如果互斥锁的使用不当,可能会导致死锁的发生。
死锁是一种进程无法继续执行的状态,它会导致系统的停滞。
操作系统实验报告范文模板
操作系统实验报告范文模板这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
操作系统上机实验报告班级:学号:姓名:实验地点:实验时间:这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
实验一进程的建立【实验目的】创建进程及子进程在父子进程间实现进程通信【实验软硬件环境】Linu某、Window98、Window2000【实验内容】创建进程并显示标识等进程控制块的属性信息;显示父子进程的通信信息和相应的应答信息。
(进程间通信机制任选)【实验程序及分析】编程思路:首先本程序在Linu某用C语言完成的,父子进程的创建用fork函数来实现,然后是父子进程间的通信,这里用pipe实现。
可以定义chan1[2],chan1[2],chan某[0]表示读,chan某[1]表示写。
他们配合使用。
【实验截图】【实验心得体会】通过这次上机练习,我熟悉了用c++实现进程的创建,销毁,父子进程间的通讯等一系列课程中需要学习的内容。
本来进程的概念在一开始我始终无法清晰地理解,但是通过自己用mfc的方法去实现它后,我开始慢慢地理解操作系统的进程的运作机制。
虽然,我只是实现了一个父子进程的创建和通讯,但是,管中窥豹,我想自己开始明白一个操作系统正是由很多这种进程实现功能的。
其中,系统整体的进程调度,管理等等还有很多东西等着我们去进一步学习、理解。
实验二进程间的同步【实验目的】这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
理解进程同步和互斥模型及其应用【实验软硬件环境】Linu某、Window98、Window2000【实验内容】利用通信API实现进程之间的同步:建立司机和售票员进程;并实现他们间的同步运行。
南昌大学操作系统实验报告材料二编程模拟进程间地同步和互斥
南昌大学实验报告---(2)编程模拟进程间的同步和互斥学生姓名:张皓然学号: 5501215001 专业班级:本硕151 实验类型:□验证□综合■设计□创新实验日期: 2017.5.5 实验成绩:一、实验目的通过实验加强对进程同步和互斥的理解,并掌握进程(线程)的创建和调用方法。
学会使用信号量解决资源共享问题。
学生可以自己选择在Windows或Linux系统下编写。
二、实验内容(一)以下为Linux系统下参考程序,请编译、运行并观察程序的输出,并分析实验结果,写出实验报告。
#include<stdio.h>//标准输入输出头文件#include<stdlib.h>//standard library标准库头文件#include<unistd.h>//POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数。
#include<time.h>//time.h是C标准库头文件,主要是一些和时间相关的函数#include<sys/types.h>//基本系统数据类型#include<sys/wait.h>//declarations for waiting#include<linux/sem.h>//Semaphore operation flags#define NUM_PROCS 5//5个子进程#define SEM_ID 250//信号量#define FILE_NAME "/tmp/sem_aaa"#define DELAY 4000000void update_file(int sem_set_id, char *file_path, int number){struct sembuf sem_op;FILE *file;//建立一个文件指针//等待信号量的数值变为非负数,此处设为负值,相当于对信号量进行P操作sem_op.sem_num=0;sem_op.sem_op=-1;sem_op.sem_flg=0;semop(sem_set_id,&sem_op,1);/*操作一组信号,进程的标识符号为sem_set_id,sem_op是结构指针。
操作系统实验-进程同步与互斥
操作系统实验-进程同步与互斥实验四:进程的管道通信实验题目进程的管道通信实验目的加深对进程概念的理解,明确进程和程序的区别。
学习进程创建的过程,进一步认识进程并发执行的实质。
分析进程争用资源的现象,学习解决进程互斥的方法。
学习解决进程同步的方法。
掌握Linux系统中进程间通过管道通信的具体实现实验内容使用系统调用pipe()建立一条管道,系统调用fork()分别创建两个子进程,它们分别向管道写一句话,如:Child process1 is sending a message!Child process2 is sending a message!父进程分别从管道读出来自两个子进程的信息,显示在屏幕上。
当然,仅仅通过屏幕上输出这两句话还不能说明实现了进程的管道通信,为了能够更好的证明和显示出进程的同步互斥和通信,在其中要加入必要的跟踪条件,如一定的输出语句等,来反映程序的并发执行情况实验要求这是一个设计型实验,要求自行、独立编制程序。
两个子进程要并发执行。
实现管道的互斥使用。
当一个子进程正在对管道进行写操作时,另一个欲写入管道的子进程必须等待。
使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定。
实现父子进程的同步,当父进程试图从一空管道中读取数据时,便进入等待状态,直到子进程将数据写入管道返回后,才将其唤醒。
为了清楚的反应进程的同步,在子进程完成相应的操作后,调用sleep()函数睡眠一段时间(程序中定为3s)。
父进程先执行wait()函数,当有子进程执行完毕后,会得到子进程的返回结果并清理子进程。
若子进程没执行完,父进程一直执行wait()进行监听,知道有一个子进程执行完成为僵尸进程。
程序中用到的系统调用因为程序时在linux系统上进行编写的,所以其中要利用到相关的linux提供的系统调用。
所用到的系统调用包含在如下头文件中。
#include#include#include#include#include#includefork() 用于创一个子进程。
进程同步与互斥实验总结
进程同步与互斥实验总结实验目的1、进一步认识并发执行的实质2、分析进程竞争资源的现象,学习解决进程同步互斥的方法实验内容1、编写程序,使用相关函数实现父子进程对共享文件的同步互斥访问。
2、修改程序,观察对临界资源访问的互斥控制的作用。
实验基础一、临界资源的互斥访问。
为了实现多进程对临界资源的互斥访问,一个进程访问临界资源的典型程序段类似如下形式:进入区临界区;退出区其余代码;其中,进入区中判断资源是否可用,如果可用,则资源数量减1,进程进入临界区;否则进程阻塞等待。
退出区中资源数量加1,唤醒阻塞等待该资源的进程。
进入区和退出区都是原子操作。
操作系统中,通常用信号量来实现进入区和退出区,即P操作和V操作。
为了实现用户程序中对某些资源的同步互斥访问,操作系统也提供了一些函数接口,功能类似于对特定临界区的进入区和退出区功能。
二、相关的系统调用。
e):用作锁定文件的某些段或者整个文件。
函数原型:#include intlockf(intfiles,intfunction;longsize)其中:files是文件描述符;参数function可以取以下值:F_LOCK:锁定一个区域。
F_ULOCK:解除锁定。
参数size指明了从文件当前位置开始的一段连续锁定区域的长度,当size为0时,锁定记录将由当前位置一直扩展到文件尾。
如果lockf的参数function 取值为F_LOCK,而指定文件的对应区域已被其他进程锁定,那么lockf的调用进程将被阻塞直到该区域解锁。
通过使用lockf函数,可实现多进程对共享文件进行互斥访问。
进程的实现中,必须使得每个进程在使用文件前对文件加锁,使用文件后解锁。
(22)openopen:打开一个文件:打开一个文件函数原型:#include#include#includeintopen(char*path,intflags,mode_tmode);其中:参数path是指向所要打开的文件的路径名指针。
实验二-----进程的同步
实验二:编程实现经典互斥和同步问题1.实验目的:加深对信号量、PV操作、进程同步和互斥等概念的理解,掌握PV操作的具体实现方法,熟练掌握进程同步和互斥的实现办法,能利用信号量机制解决实际生活中的同步和互斥问题。
2.实验内容(1)、编程实现P操作原语、V操作原语,(2)、用所定义的PV操作解决下面的问题:设学院某教室共有座位30个,任何时刻最多可容纳30名同学进入自习,当教室内人数少于30名时,则教室外等待的同学可立即进入,否则需在外面等待。
把一个欲进入教室自习的同学看作一个进程。
3、实验具体内容和步骤的说明(1)用户进程的定义(2)信号量的定义及初始化(3)PV操作的定义P操作顺序执行下述两个动作:①信号量的值减1,即S=S-1;②如果S≥0,则该进程继续执行(挂入就绪队列);如果S<0,则把该进程的状态置为阻塞态,把相应的PCB连入该信号量队列的末尾,并放弃处理机,进行等待(直至其它进程在S上执行V操作,把它释放出来为止)。
(挂入阻塞队列)V操作顺序执行下述两个动作:①S值加1,即S=S+1;②如果S>0,则该进程继续运行;(直接挂入就绪队列)如果S≤0,则释放信号量队列上的第一个PCB(即信号量指针项所指向的PCB)所对应的进程(把阻塞态改为就绪态),执行V操作的进程继续运行。
从阻塞队列唤醒一个进程,即从阻塞队列删除,挂入就绪队列(4)写出对应的主函数,解决多名同学之间的同步问题提示:设置2个进程队列,一是已经进入教室的,即就绪队列二是等待进入教室的,即阻塞队列程序:#include <stdio.h>#include <stdlib.h>typedef struct node{int name; //进程IDchar state;//进程状态struct node *next;}PCB;int s=3;//资源数PCB *stophead=NULL,*stoptail=NULL,*readyhead=NULL,*readytail=NULL;//阻塞就绪队列头尾指针void block(PCB *q)//无资源尾插入阻塞队列{q->state='B';if(stophead==NULL){stophead=q;stoptail=q;}else{stoptail->next=q;stoptail=q;}}void wakeup()//唤醒阻塞队列头节点尾插入就绪队列{stophead->state='R';if(readyhead==NULL){readyhead=stophead;readytail=stophead;stophead=stophead->next;readytail->next=NULL;}else{readytail->next=stophead;readytail=stophead;stophead=stophead->next;readytail->next=NULL;}}void p(PCB *q)//p操作{s=s-1;if(s<0)//无资源则插入阻塞队列block(q);else//尾插入就绪队列{q->state='R';if(readyhead==NULL){readyhead=q;readytail=q;}else{readytail->next=q;readytail=q;}}}int v(int b)//v操作{PCB *q,*pre;if(readyhead==NULL)//无就绪进程返回{printf(" 无就绪进程!\n\n");return 0;}pre=readyhead;q=readyhead;while(q->name!=b)//寻找就绪队列中v操作节点{if(q->next==NULL)//无当前查找节点{printf(" 查无此就绪进程!\n\n");return 1;}pre=q;q=q->next;//查找成功if(readyhead==readytail)//就绪队列仅有一个节点{readyhead=readytail=NULL;free(q);s=s+1;return 0;}else//就绪队列有多个节点{if(q==readyhead){readyhead=readyhead->next;free(q);//释放节点}else if(q==readytail){readytail=pre;pre->next=NULL;free(q);}else{pre->next=q->next;free(q);}s=s+1;if(s<=0)//如有阻塞进程则唤醒加入就绪队列wakeup();return 1;}}void show()//输出当前所有进程状态{PCB *q;q=readyhead;printf("\n");printf(" ID STATE\n");while(q!=NULL)printf("%5d%5c\n",q->name,q->state);q=q->next;}q=stophead;while(q!=NULL){printf("%5d%5c\n",q->name,q->state);q=q->next;}}void main(void){PCB *q;char a;int b;printf("\n剩余资源数%d ",s);printf("PLEASE INPUT:");scanf("%c %d",&a,&b);getchar();//输入当前操作类型进程ID (如p 1)while(a!='0')// (0 0)退出{if(a=='p')//执行p操作{q=(PCB *)malloc(sizeof(PCB));//进程初始化q->name=b;q->next=NULL;p(q);}else if(a=='v')//执行v操作b=v(b);if(b!=0)show();//显示当前进程状态printf("\n剩余资源数%d ",s);printf("PLEASE INPUT:");scanf("%c %d",&a,&b);getchar();}}。
进程互斥与进程同步实验
· · · · · · · · · · · · · · · · · · · · · · · · · · sem_wait(&s_sem); /*对信号量的 P 操作*/ 临界区语句; sem_post(&full_sem); /*对信号量的 V 操作*/ · · · · · · · · · · · · · · · · · · · · · · · · · · 实例:一般情况下的生产者消费者问题 程序名:ProducerConsumer.c 程序正文:可分两种情况 (1) Linux 版本 /*多个生产者多个消费者多个缓冲区*/ #include <stdio.h> #include <stdlib.h> # include <unistd.h>*/ #include <pthread.h> #include <semaphore.h> #define M 10 /* 缓冲区数目*/ #define #define NP 6 /*生产者数目*/ NC 4 /*消费者数目*/
1 POSIX 线程编程基础
POSIX 线程模型中创建线程使用 pthread_t 变量,其步骤为: 声明:pthread_t a_thread; 创建:使用函数
int pthread_create(pthread_t *p, const pthread_attr_t *attr, void *(*start_rtn)(void),void *arg);
返回值: 如果正常创建,返回 0;否则返回一个非零的值。 第一个参数:pthread_t 变量(线程变量)的名字; 第二个参数:设置线程属性。 第三个参数:线程运行函数的起始地址(即函数名) 。 第四个参数:线程运行函数的参数。
操作系统实验报告——进程同步与互斥
《进程同步与互斥》实验报告实验序号:01 实验项目名称:进程同步与互斥学号姓名专业、班实验地点指导教师时间一、实验目的1、掌握基本的进程同步与互斥算法,理解生产者-消费者问题。
2、学习使用Windows 2000/XP中基本的同步对象,掌握相关API的使用方法。
3、了解Windows 2000/XP中多线程的并发执行机制,实现进程的同步与互斥。
4、设计程序,实现生产者-消费者进程(线程)的同步与互斥;二、实验环境Windows 2000/XP + Visual C++ 6.0三、实验内容以生产者-消费者模型为依据,在Windows 2000/XP环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
四、设计思路和流程框图生产者进程的功能:生产东西,供消费者消费;消费者进程的功能:消费生产者生产的东西。
生产者生产产品并存入缓冲区供消费者取走使用,消费者从缓冲器内取出产品去消费。
在生产者和消费者同时工作时,必须禁止生产者将产品放入已装满的缓冲器内,禁止消费者从空缓冲器内取产品。
五、源程序(含注释)清单#include<windows.h>printf("Consumer %2d finish consuming product %2d\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}六、测试结果以及实验总结1、通过实验进一步了解了基本的进程同步与互斥算法,理解生产者-消费者问题2、掌握了相关API的使用方法。
3、了解到进程是一个可以拥有资源的基本单位,是一个可以独立调度和分派的基本单位。
而线程是进程中的一个实体,是被系统独立调度和分配的基本单位,故又称为轻权(轻型)进程(Light Weight Process)。
操作系统实训报告进程同步和互斥
进程同步和互斥一、设计目的:通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
二、设计内容哲学家有N个,也定全体到达后开始讨论:在讨论的间隙哲学家进餐,每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
三、开发环境windows环境,VC6.0平台。
四、分析设计<一>实验原理不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
每个进程中访问临界资源的那段代码称为临界区(Critical Section)。
每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。
每次只准许一个进程进入临界区,进入后不允许其他进程进入。
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
本程序主要使用了EnterCriticalSection (&cs)和LeaveCriticalSection (&cs)两个函数实现临界区互斥。
EnterCriticalSection (&cs)用来进入临界区,LeaveCriticalSection (&cs)用来离开临界区。
哲学家进餐问题设定图<二>程序结构1、主程序模块(详见图1)2、状态改变模块(详见图2)3、返回哲学家状态模块(详见图3)4、返回餐具状态模块(详见图4)<三>数据结构:程序中定义一个哲学家类,包含两个私有对象和四个公有对象。
Number对象:报讯哲学家的编号。
Status对象:用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考Philosopher(int num)方法:哲学家类构造函数,参数num表示哲学家编号find() const方法:返回该哲学家编号getinfo() const方法:返回哲学家当前状态Change()方法:根据题目要求改变哲学家的状态(等待->进餐->思考->等待…………)另外,程序中包含一个公有对象,bool类型数组tools[6],用来保存6把餐当前状态:true 表示该餐具当前空闲,false表示该餐具当前正被使用。
计算机操作系统课程设计报告-进程间的通信与互斥
操作系统课程设计报告专业:计算机科学与技术姓名:**学号:************日期:2014.9.21一、课程设计内容调用linux系统调用实现多进程的创建、进程间同步与互斥。
二、课程设计目的1、加深对进程概念的理解,明确进程和程序的区别2、进一步认识并发执行的实质3、分析进程竞争资源现象,学习解决进程互斥的方法4、了解Linux系统中进程通信的基本原理三、课程设计题目1.进程的创建◆任务:编写一段程序,使用系统调用fork( )创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。
让每一个进程在屏幕上显示一个字符:父进程显示字符a,自进程分别显示字符b和字符c。
试观察、记录并分析屏幕上进程调度的情况。
如果在程序中使用系统调用nice( )来改变各进程的优先级,会出现什么现象?◆程序:// 文件process1.cpp#include<iostream>#include<unistd.h>#include<sys/types.h>using namespace std;int main(){pid_t pid1, pid2; //两个子进程变量//创建进程pid1if (pid1 = fork()) //pid1!=0,是父进程{//创建进程pid2if (pid2 = fork()) //pid2!=0, 是父进程,输出'a'cout<<'a'<<endl;else //子进程pid2输出'c'cout<<'c'<<endl;}else //子进程pid1输出'b'cout<<'b'<<endl;return 0;}◆运行结果:从运行结果来看,只出现了acb。
并且最先执行了父进程,父进程return之后,两个子进程才开始执行。
操作系统进程同步实验报告
操作系统进程同步实验报告本实验旨在通过模拟操作系统中进程的同步问题,加深学生对操作系统中进程同步机制的了解和实践能力。
本次实验分为两个部分,第一个部分是使用信号量实现进程同步,第二个部分是使用管程实现进程同步。
第一部分实验:使用信号量实现进程同步本部分实验的目标是使用信号量来实现进程同步,确保资源的互斥访问。
在Linux系统中,信号量是一种用来控制进程同步的机制,可以用于保证共享资源的互斥访问、避免死锁等问题。
具体实验流程如下:1. 定义一个信号量,用于互斥访问共享资源在Linux系统中,使用semget函数可以创建一个信号量集,使用semctl函数可以对信号量进行控制。
```#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define KEY 1234 // 定义信号量的键值int semid; // 定义信号量标识符union semun{int val; // 信号量的初始值struct semid_ds *buf; // IPC_STAT, IPC_SET操作时用ushort *array; // GETALL, SETALL操作时用};void init_sem(){int ret;union semun semunion;// 创建信号量semid = semget(KEY, 1, IPC_CREAT | 0666);if(semid == -1){perror("semget error");exit(1);}2. 定义生产者和消费者进程,并使用信号量来实现同步在生产者和消费者进程中,需要先对信号量进行P操作,即申请资源,然后进行对共享资源的操作,最后再对信号量进行V操作,即释放资源。
本实验中,共享资源是一个循环缓冲区,生产者进程向其中写入数据,消费者进程从中读取数据。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#defineSEM_ID 250//信号量
#define "/tmp/sem_aaa"
#defineDELAY 4000000
voidupdate_ sem_set_id,char *,int number){
ﻩstructsembufsem_op;
#include<stdio.h>//标准输入输出头文件
#include<stdlib.h>//standardlibrary标准库头文件
#include<unistd.h>//POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数。
}
(二)生产者消费者问题
生产者消费者问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
for(i=0;i<3;i++){
update_,);
for(j=0;j<4000000;j++);
}
}
int main(intargc,char **argv)
{
intsem_set_id; //信号量集的ID
ﻩunionsemun sem_val; //信号量的数值,用于semctl()
ﻩintchild_pid;
FILE*建立一个文件指针
ﻩ//等待信号量的数值变为非负数,此处设为负值,相当于对信号量进行P操作
ﻩsem_op.sem_num=0;
ﻩsem_op.sem_op=-1;
sem_op.sem_flg=0;
ﻩsemop(sem_set_id,&sem_op,1);
/*操作一组信号,进程的标识符号为sem_set_id,sem_op是结构指针。
for(i=0;i<NUM_PROCS;i++){
//通过fork()函数创建子进程
ﻩchild_pid=fork();
switch(child_pid){
ﻩcase -1:
ﻩﻩperror("fork");
ﻩﻩcase0: //子进程写文件
do_child_loop(sem_set_id,);
ﻩﻩexit(0);
#include <sys/mman.h>
#include<sys/types.h>
ﻩint i;
ﻩintrc;
//建立信号量集,ID是250,其中只有一个信号量
sem_set_id=semget(SEM_ID,1,IPC_CREAT|0600);
if(sem_set_id==-1){//若调用失败,输出错误类型,强制退出程序
perror("main: semget");
ﻩexit(1);
ﻩ}
//把第一个信号量的数值设置为1
ﻩsem_val.val=1;
ﻩrc=semctl(sem_set_id,0,SETVAL,sem_val);
if(rc==-1)
ﻩ{//测试是否成功调用semclt()函数
perror("main:semctl");
exit(ห้องสมุดไป่ตู้);
}
//建立一些子进程,使它们可以同时以竞争的方式访问信号量
sem_op:如果其值为正数,该值会加到现有的信号内含值中,通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值,通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。*/
//写文件,写入的数值是当前进程的进程号
ﻩdefault: //父进程接着运行
ﻩbreak;
}
ﻩ}
ﻩ//等待子进程结束
for(i=0;i<NUM_PROCS;i++){
ﻩint child_status;
wait(&child_status);
ﻩ}
printf("main:we'redone\n");
fflush(stdout);
return0;
实验类型:□验证□综合■设计□创新实验日期:2017.5.5实验成绩:
一、实验目的
通过实验加强对进程同步和互斥的理解,并掌握进程(线程)的创建和调用方法。学会使用信号量解决资源共享问题。学生可以自己选择在Windows或Linux系统下编写。
二、实验内容
(一)以下为Linux系统下参考程序,请编译、运行并观察程序的输出,并分析实验结果,写出实验报告。
南昌大学操作系统实验报告二编程模拟进程间的同步和互斥
———————————————————————————————— 作者:
———————————————————————————————— 日期:
ﻩ
南昌大学实验报告
---(2)编程模拟进程间的同步和互斥
学生姓名:张皓然学号:5501215001专业班级:本硕151
#include<time.h>//time.h是C标准库头文件,主要是一些和时间相关的函数
#include<sys/types.h>//基本系统数据类型
#include<sys/wait.h>//declarations for waiting
#include<linux/sem.h>//Semaphore operationflags
(,"w");
//写文件,若成功则返回文件起始地址;否则置0
if(file){//临界区
ﻩfprintf(file,"%d\n",number);//将进程号写入*file处
ﻩﻩprintf("%d\n",number);将当前的进程号输到标准输出里。
ﻩﻩfclose(关闭文件
}
ﻩ//发送信号,把信号量的数值加1,此处相当于对信号量进行V操作
sem_op.sem_num=0;
sem_op.sem_op=1;
ﻩsem_op.sem_flg=0;
semop(sem_set_id,&sem_op,1);
}
//子进程写文件
void do_child_loop(intsem_set_id,char *){
pid_t pid=getpid();
ﻩinti,j;//取得目前进程的识别码,返回当前的进程的标识符