北邮 操作系统 实验一 进程同步

北邮 操作系统 实验一 进程同步
北邮 操作系统 实验一 进程同步

实验一进程同步

1.实习要求

在Windows 环境下,创建一个包含n 个线程的控制进程。用这n 个线程来表示n

个读者或写者。每个线程按相应测试数据文件的要求,进行读写操作。请用信号量

机制分别实现读者优先和写者优先的读者-写者问题。

读者-写者问题的读写操作限制:

1)写-写互斥;

2)读-写互斥;

3)读-读允许;

读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,

则该读者可直接开始读操作。

写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。

运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读

写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。

2.测试数据文件格式

测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写

操作的开始时间和持续时间。每行测试数据包括四个字段,各字段间用空格分隔。第一字段为一个正整数,表示线程序号。第一字段表示相应线程角色,R 表示读者是,W 表示写者。第二字段为一个正数,表示读写操作的开始时间。线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。第三字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。下面是一个测试数据文件的例子:

1 R 3 5

2 W 4 5

3 R 5 2

4 R 6 5

5 W 5.1 3

3.本实验的相关知识

3.1进程

进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

3.2线程

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有

一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,那就是程序本身。

线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

3.3 同步和互斥

进程互斥是进程之间发生的一种间接性作用,一般是程序不希望的。通常的情况是两个或两个以上的进程需要同时访问某个共享变量。我们一般将发生能够问共享变量的程序段成为临界区。两个进程不能同时进入临界区,否则就会导致数据的不一致,产生与时间有关的错误。解决互斥问题应该满足互斥和公平两个原则,即任意时刻只能允许一个进程处于同一共享变量的临界区,而且不能让任一进程无限期地等待。互斥问题可以用硬件方法解决;也可以用软件方法。

同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

4. 函数

4.1 线程控制

4.1.1 CreateThread

完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD

DWORD dwStackSize, // initial stack size

LPTHREAD_START_ROUTINE lpStartAddress, // thread

function

LPVOID lpParameter, // thread argument

DWORD dwCreationFlags, // creation option

LPDWORD lpThreadId // thread identifier

);

4.1.2 ExitThread

用于结束当前线程。

VOID ExitThread(

DWORD dwExitCode // exit code for this thread

);

4.1.3 Sleep

可在指定的时间内挂起当前线程。

VOID Sleep(

DWORD dwMilliseconds // sleep time

);

4.1.4 信号量控制:CreateMutex

创建一个互斥对象,返回对象句柄;

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD BOOL bInitialOwner, // initial owner

LPCTSTR lpName // object name

);

4.1.5 OpenMutex

打开并返回一个已存在的互斥对象句柄,用于后续访问;HANDLE OpenMutex(

DWORD dwDesiredAccess, // access

BOOL bInheritHandle, // inheritance option LPCTSTR lpName // object name

);

4.1.6 ReleaseMutex

释放对互斥对象的占用,使之成为可用。

BOOL ReleaseMutex(

HANDLE hMutex // handle to mutex

);

4.1.7 WaitForSingleObject

可在指定的时间内等待指定对象为可用状态;

DWORD WaitForSingleObject(

HANDLE hHandle, // handle to object

DWORD dwMilliseconds // time-out interval

);

4.2 程序分析

4.2.1 读者优先模式:

读者进程:

RP_ReaderThread()

P(mutex);

read_count++;

if(read_count==1)//如果有读者开始读操作,则停止写操作P(&RP_Write);

V(mutex);

-----------------------------------------------------

读临界区……

-----------------------------------------------------

P(mutex);

read_count--;

if(read_count==0)//所有读者读操作完毕,开放写操作

V(&RP_Write);

V(mutex);

写者进程:

RP_WriterThread函数的实现如下:

P(&RP_Write);

---------------------------------------------

写临界区……

---------------------------------------------

V(&RP_Write);

4.2.2 写者优先模式:

读者进程:

WP_ReaderThread()

P(mutex1);

P(&cs_Read);

P(mutex2);

read_count++;

if(read_count==1)//有读者开始读操作,写者等待

P(&cs_Write);

V(mutex2);

V(&cs_Read);

V(mutex1);

--------------------------------------

读临界区……

--------------------------------------

P(mutex2);

read_count--;

if(read_count==0)//所有读者完成读操作,开放写操作

V(&cs_Write);

V(mutex2);

写者进程:

WP_WriterThread()

P(mutex3);

write_count++;

if(write_count==1)//有写者要进行操作,之后的读者全部暂停,直到写者完成操作P(&cs_Read);

V(mutex3);

P(&cs_Write);

----------------------------------

写临界区……

----------------------------------

V(&cs_Write);

P(mutex3);

write_count--;

if(write_count==0)//所有写者完成操作,开放读者读操作

V(&cs_Read);

V(mutex3);

4.3 代码

头文件

#include "windows.h"

#include

#include

#include

#include

#include

#include

#define READER 'R' //读者

#define WRITER 'W' //写者

#define INTE_PER_SEC 1000 //每秒时钟中断数目

#define MAX_THREAD_NUM 64//最大线程数目

#define MAX_FILE_NUM 32//最大数据文件数目

#define MAX_STR_LEN 32//字符串长度

全局函数

int readcount = 0;//读者数目

int writecount=0;//写者数目

CRITICAL_SECTION RP_Write;//临界区

CRITICAL_SECTION cs_Write;

CRITICAL_SECTION cs_Read;

线程结构

struct ThreadInfo

{

int serial;//线程序号

char entity;//线程类别(判断是读者线程还是写者线程)

double delay;//线程延迟

double persist;//线程读写操作持续时间

};

//读者优先-读者线程

//p:读者线程信息

void RP_ReaderThread(void* p)

{

//互斥变量

HANDLE h_Mutex;

h_Mutex =OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount"); DWORD wait_for_mutex;//等待互斥变量所有权

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); Sleep(m_delay);//延迟等待

printf("Reader thread %d sents the reading require.\n", m_serial); //等待互斥信号,保证对readcount的访问、修改和互斥

wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//P操作

//读者数目增加

readcount++;

if(readcount==1)

{

//读第一个读者,等待资源

EnterCriticalSection(&RP_Write);

}

ReleaseMutex(h_Mutex);//V操作

printf("Reader thread %d begins to read file.\n", m_serial);

Sleep(m_persist);

//退出线程

printf("Reader thread %d finished reading file.\n", m_serial);

//等待互斥信号,保证对readcount的访问、修改互斥

wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//P操作

//读者数目减少

readcount--;

if(readcount==0)

{

//如果读者全部读完,唤醒写者

LeaveCriticalSection(&RP_Write);

}

ReleaseMutex(h_Mutex);//V操作

}

//读者优先-写者线程

//写者线程信息

void RP_WriterThread(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);

Sleep(m_delay);//延迟等待

printf("Writer thread %d sents the writing require.\n", m_serial);

//等待资源

EnterCriticalSection(&RP_Write);

//写文件

printf("Writer thread %d begins to write to the file.\n", m_serial); Sleep(m_persist);

//退出线程

printf("Writer thread %d finished writing to the file.\n", m_serial); //释放资源

LeaveCriticalSection(&RP_Write);

}

//读者优先处理函数

//file:文件名

void ReaderPriority(char* file)

{

DWORD n_thread=0;//线程数目

DWORD thread_ID;//线程ID

DWORD wait_for_all;//等待所有线程结束

//互斥对象

HANDLE h_Mutex;

h_Mutex =CreateMutex(NULL,FALSE,"mutex_for_readcount");

//线程对象的数组

HANDLE h_Thread[MAX_THREAD_NUM];

ThreadInfo thread_info[MAX_THREAD_NUM];

readcount=0;//初始化readcount

InitializeCriticalSection(&RP_Write);//初始化临界区

ifstream inFile;

inFile.open(file);//打开文件

printf("Reader Priority:\n\n");

while(inFile)

{

//读入每一个读者、写者的信息

inFile>>thread_info[n_thread].serial;

inFile>>thread_info[n_thread].entity;

inFile>>thread_info[n_thread].delay;

inFile>>thread_info[n_thread++].persist;

inFile.get();

}

for(int i=0; i<(int)(n_thread); i++)

{

if (thread_info[i].entity==READER||thread_info[i].entity=='r')

{

//创建读者进程

h_Thread[i]=CreateThread(NULL,0,

(LPTHREAD_START_ROUTINE)(RP_ReaderThread), &thread_info[i],

0,&thread_ID);

}

else{

//创建写者进程

h_Thread[i]=CreateThread(NULL,0,

(LPTHREAD_START_ROUTINE)(RP_WriterThread), &thread_info[i],

0,&thread_ID);

}

}

//等待所有线程结束

wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1); printf("All reader and writer have finished operating.\n");

}

//写者优先--读者进程

//p:读者线程信息

void WP_ReaderThread(void* p)

{

//互斥变量

HANDLE h_mutex1;

h_mutex1=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex1");

HANDLE h_mutex2;

h_mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");

DWORD wait_for_mutex1;//等待互斥变量所有权

DWORD wait_for_mutex2;

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); Sleep(m_delay);//延迟等待

printf("Reader thread %d sents the reading require.\n", m_serial); wait_for_mutex1=WaitForSingleObject(h_mutex1,-1);//P操作

//进入读者临界区

EnterCriticalSection(&cs_Read);//P操作

//阻塞互斥对象mutex2,保证对readcount的访问、修改互斥

wait_for_mutex2=WaitForSingleObject(h_mutex2,-1);//P操作

//修改读者数目

readcount++;

if(readcount==1)

{

//如果是第一个读者,等待写者写完

EnterCriticalSection(&cs_Write);

}

ReleaseMutex(h_mutex2);//V操作

//让其他读者进入临界区

LeaveCriticalSection(&cs_Read);

ReleaseMutex(h_mutex1);//V操作

//读文件

printf("Reader thread %d begins to read file.\n", m_serial);

Sleep(m_persist);

//退出线程

printf("Reader thread %d finished reading file.\n", m_serial);

//阻塞互斥对象mutex2,保证对readcount的访问、修改互斥

wait_for_mutex2=WaitForSingleObject(h_mutex2,-1);//P操作

readcount--;

if(readcount==0)

{

//如果所有读者读完,唤醒写者

LeaveCriticalSection(&cs_Write);

}

ReleaseMutex(h_mutex2);//V操作

}

//写者优先--写者线程

//p:写者线程信息

void WP_WriterThread(void* p)

{

DWORD wait_for_mutex3;

DWORD m_delay;//延迟时间

DWORD m_persist;//写文件持续时间

int m_serial;//线程序号

//互斥对象

HANDLE h_mutex3;

h_mutex3=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex3");

//从参数中获得信息

m_serial=((ThreadInfo*)(p))->serial;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);

m_persist=(DWORD)(((ThreadInfo*)(p))-> persist *INTE_PER_SEC); Sleep(m_delay);//延迟等待

printf("Writer thread %d sents the writing require.\n", m_serial); //阻塞互斥对象mutex3,保证对writecount的访问、修改互斥

wait_for_mutex3=WaitForSingleObject(h_mutex3,-1);//P操作

//修改写者数目

writecount++;

if(writecount==1)

{

//第一个写者,等待读者读完

EnterCriticalSection(&cs_Read);

}

ReleaseMutex(h_mutex3);//V操作

//进入写者临界区

EnterCriticalSection(&cs_Write);

//写文件

printf("Writer thread %d begins to write to the file.\n", m_serial); Sleep(m_persist);

//退出线程

printf("Writer thread %d finished writing to the file.\n", m_serial); //离开临界区

LeaveCriticalSection(&cs_Write);

//阻塞互斥对象mutex3,保证对writecount的访问、修改互斥

wait_for_mutex3=WaitForSingleObject(h_mutex3,-1);//P操作

writecount--;

if(writecount==0)

{

//写者写完,读者可以读

LeaveCriticalSection(&cs_Read);

}

ReleaseMutex(h_mutex3);//V操作

}

//写者优先处理函数

//file:文件名

void WriterPriority(char* file)

{

DWORD n_thread=0;//线程数目

DWORD thread_ID;//线程ID

DWORD wait_for_all;//等待所有线程结束

//互斥对象

HANDLE h_Mutex1;

h_Mutex1 =CreateMutex(NULL,FALSE,"mutex1");

HANDLE h_Mutex2;

h_Mutex2 =CreateMutex(NULL,FALSE,"mutex2");

HANDLE h_Mutex3;

h_Mutex3 =CreateMutex(NULL,FALSE,"mutex3");

//线程对象

HANDLE h_Thread[MAX_THREAD_NUM];

ThreadInfo thread_info[MAX_THREAD_NUM];

readcount=0;//初始化readcount

writecount=0;//初始化writecount

InitializeCriticalSection(&cs_Write);//初始化临界区InitializeCriticalSection(&cs_Read);

ifstream inFile;

inFile.open(file);//打开文件

printf("Writer Priority:\n\n");

while(inFile)

{

//读入每一个读者、写者的信息

inFile>>thread_info[n_thread].serial;

inFile>>thread_info[n_thread].entity;

inFile>>thread_info[n_thread].delay;

inFile>>thread_info[n_thread++].persist;

inFile.get();

}

for(int i=0; i<(int)(n_thread); i++)

{

if (thread_info[i].entity==READER||thread_info[i].entity=='r') {

//创建读者进程

h_Thread[i]=CreateThread(NULL,0,

(LPTHREAD_START_ROUTINE)(RP_ReaderThread), &thread_info[i],

0,&thread_ID);

}

else{

//创建写者进程

h_Thread[i]=CreateThread(NULL,0,

(LPTHREAD_START_ROUTINE)(RP_WriterThread), &thread_info[i],

0,&thread_ID);

}

}

//等待所有线程结束

wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1); printf("All reader and writer have finished operating.\n");

}

//主函数

int main(int argc,char* argv[])

{

char ch;

while(true)

{

//打印提示信息

printf("****************************************************\n"); printf(" 1:Reader Priority\n");

printf(" 2:Writer Priority\n");

printf(" 3:Exit to Windows \n");

printf("****************************************************\n"); printf("Enter your choice(1,2 or 3):");

//如果信息不正确,继续输入

do{

ch=(char)_getch();

}while(ch!='1'&&ch!='2'&&ch!='3');

system("cls");

//选择3,返回

if(ch=='3')

return 0;

//选择1,读者优先

else if (ch=='1')

ReaderPriority("thread.dat");

//选择2,写者优先

else

WriterPriority("thread.dat");

//结束

printf("\nPress Any Key To Continue:");

_getch();

system("cls");

}

return 0;

}

5.实验结果

输入1:

输入2:

北邮网络-操作系统原理-阶段作业三

一、单项选择题(共10道小题,共100.0分) 1. 不支持记录等结构的文件类型是 A. 顺序文件 B. 索引顺序文件 C. 索引文件 D. 哈希文件 2. 在I/O系统层次模型中处于最高的一个层次,负责所有设备I/O工作中均 要用到的共同的功能的模块是 A. 系统服务接口 B. I/O子系统 C. 设备驱动程序接口 D. 设备驱动程序 3. 在采用局部转换策略进行页面置换的系统中,一个进程得到3个页架。系 统采用先进先出的转换算法,该进程的页面调度序列为:1,3,2,6,2,5,6,4,6。如果页面初次装入时不计算为缺页,请问该进程在调度中会产生几次缺页。 A. 6次 B. 5次 C. 4次 D. 3次

4. 完成从物理页架号到虚地址的映射是 A. 页表 B. 反向页表 C. 多级页表 D. 快表 5. 下列设备中,()为块设备。 A. 软盘驱动器 B. MODEM C. 声卡 D. 鼠标 6. 在下列的实存管理技术中,同一进程在连续地址存储的技术是 A. 可变分区多道管理技术 B. 多重分区管理 C. 简单分页 D. 简单分段

7. 采用简单分页系统的内存管理,页面的大小是8K字节。现有一个逻辑地 址A=3580h,该进程的页表为 [0,5/1,6/2,1/3,0...],则该逻辑地址对应的物理地址A'=() A. 0580h B. D580h C. 6580h D. 7580h 8. 对于实存管理技术,实际上它不具备的功能有: A. 主存分配 B. 地址转换和重定位 C. 存储保护和主存共享 D. 存储扩充 9. 在当前的计算机系统中,通常是按()进行编址。 A. 位 B. 字节

操作系统进程同步实验报告

实验三:进程同步实验 一、实验任务: (1)掌握操作系统的进程同步原理; (2)熟悉linux的进程同步原语; (3 )设计程序,实现经典进程同步问题。 二、实验原理: (1)P、V操作 PV操作由P操作原语和V操作原语组成(原语是不可中断的过程) ,对信号量进行操作,具体定义如下: P( S):①将信- 号量S的值减1,即S=S-1; ②如果S30,则该进程继续执行;否则该进程置为等待状态,排入等待队列。 V( S):①将信号量S的值加1,即S=S+1 ; ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。 (2)信号量 信号量(semaphore )的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的 值仅能由PV操作来改变。 一般来说,信号量S30时,S表示可用资源的数量。执行一次P操作意味着请求分配一 个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S 的值加1;若S均,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。 (3)linux的进程同步原语 ①wait();阻塞父进程,子进程执行; ②#in clude #in clude key_t ftok (char*path name, char proj) ;它返回与路径path name 相对应的一个键值。 ③int semget(key_t key, int n sems, int semflg) 参数key是一个键值,由ftok获得,唯一标识一个信号灯集,用法与msgget()中的key 相同;参数nsems指定打开或者新创建的信号灯集中将包含信号灯的数目;semflg参数是一些标志位。参数key和semflg的取值,以及何时打开已有信号灯集或者创建一个新的信号灯集与msgget()中的对应部分相同。该调用返回与健值key相对应的信号灯集描述字。调用返回:成功返回信号灯集描述字,否则返回-1。 ④int semop(i nt semid, struct sembuf *sops, un sig ned n sops); semid是信号灯集ID , sops指向数组的每一个sembuf结构都刻画一个在特定信号灯上的操作。nsops为sops指向数组的大小。 ⑤int semctl(int semid , int semnum , int cmd , union semun arg) 该系统调用实现对信号灯的各种控制操作,参数semid指定信号灯集,参数cmd指定 具体的操作类型;参数semnum指定对哪个信号灯操作,只对几个特殊的cmd操作有意义;

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图

2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

操作系统的进程调度 实验报告

《计算机操作系统2》实验报告 实验一题目:操作系统的进程调度 姓名:学号:12125807 实验日期:2014.12 实验要求: 1.设计一个有n个进程工行的进程调度程序。每个进程由一个进程控制块(PCB)表示。 进程控制块通常应包含下述信息:进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。 2.调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分 析比较。 3.系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程 实验目的: 1.进程是操作系统最重要的概念之一,进程调度又是操作系统核心的主要内容。本实习要 求学生独立地用高级语言编写和调试一个简单的进程调度程序。调度算法可任意选择或自行设计。例如,简单轮转法和优先数法等。本实习可加深对于进程调度和各种调度算法的理解。 实验内容: 1.编制和调试示例给出的进程调度程序,并使其投入运行。 2.自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚 于示例。 3.直观地评测各种调度算法的性能。 示例: 1.题目 本程序可选用优先数法或简单轮转法对五个进程进行调度。每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假设起始状态都是就绪状态W。为了便于处理,程序进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。 进程控制块结构如下:

PCB 进程标识数 链指针 优先数/轮转时间片数 占用CPU时间片数 进程所需时间片数 进程状态 进程控制块链结构如下: 其中:RUN—当前运行进程指针; HEAD—进程就绪链链首指针; TAID—进程就绪链链尾指针。 2.算法与框图 (1) 优先数法。 进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。 (2) 简单轮转法。 进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。(3) 程序框图如下图所示。

操作系统实验报告(进程的创建)(DOC)

实验题目进程的创建小组合作否姓名班级学号 一、实验目的 1、了解进程的创建。 2、了解进程间的调用以及实现。 3、分析进程竞争资源的现象,学习解决互斥的方法。 4、加深对进程概念的理解,认识并发执行的本质。 二.实验环境 Windows 系统的计算机一台,安装了Linux虚拟机 三、实验内容与步骤 1、fork()系统调用的使用例子 程序代码: #include #include #include int glob=3; int main(void) { pid_t pid;int loc=3; printf("before fork();glod=%d,loc=%d.\n",glob,loc); if((pid=fork())<0) { printf("fork() error. \n"); exit(0); } else if(pid==0) { glob++; loc--; printf("child process changes glob and loc: \n"); } else

wait(0); printf("parent process doesn't change the glob and loc:\n"); printf("glob=%d,loc=%d\n",glob,loc); exit(0); } 运行结果: 2、理解vofork()调用: 程序代码: #include #include #include int glob=3; int main(void) { pid_t pid; int loc=3; if((pid=vfork())<0) { printf("vfork() error\n"); exit(0); } else if(pid==0) { glob++; loc--; printf("child process changes the glob and loc\n"); exit(0); } else printf ("parent process doesn't change the glob and loc\n"); printf("glob=%d,val=%d\n",glob,loc);

操作系统实验报告(进程调度算法)

操作系统实验报告(进程调度算法)

实验1 进程调度算法 一、实验内容 按优先数调度算法实现处理器调度。 二、实验目的 在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。 三、实验原理 设计一个按优先数调度算法实现处理器调度的程序。 (1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为: 进程名 指针 要求运行时 间 优先数

状态 其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。 指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。 要求运行时间——假设进程需要运行的单位时间数。 优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。 (2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。 (3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例: 队首标志 K2

1P1 K 2 P2 K 3 P3 K 4 P4 K 5 P5 0 K4K5K3K1 2 3 1 2 4 1 5 3 4 2 R R R R R PC B1 PC B2 PC B3 PC B4 PC B5 (4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行: 优先数-1 要求运行时间-1 来模拟进程的一次运行。 提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。

北京邮电大学2009年操作系统期末试卷

北京邮电大学2008——2009学年第一学期 《操作系统》期末考试试题(A) 1.FILL IN BLANKS (10 points) 1.1 A _trap___ is a software-generated interrupt caused either by an error or by a specific request from a user program that an operating-system services be performed. 1.2 A ______ is used in Unix systems to notify a process that a particular event has occurred. 1.3 To manage the process executing, OS records the state and other information (e.g. the priority) of the process in . 1.4 The scheduling criteria include CPU utilization, throughput, turnaround time, waiting time, and response time .

1.5 For n concurrent processes that mutual exclusively use some resources, the code segmentations, in which the processes access the resources, are called deadlock . 1.6. The ___visual memory___ scheme enables users to run programs that are larger than actual physical memory, this allows the execution of a process that is not completely in memory. 1.7. The __FIFO___ page replacement algorithm associates with each page the time when that page was brought into memory. When a page must be replaced, the oldest page is chosen. 1.8The file system resides permanently on , which is designed to hold a large amount of data permanently. 1.9The file system itself is generally composed of many different levels, including the logical file system, the file-organization module, the and the I/O control. 1.10 T he kernel’s I/O subsystem provides numero us services. Among these are I/O scheduling, , caching, spooling, device reservation, and error handling, and name translation. 2.CHOICE ( 10 points ) 2.1 _____ operating systems have well defined, fixed time constraints. Processing must be done within the defined constrains, or the system will fail. A. Multimedia B. Real-time C. Clustered D. Network 2.2 Which one of the following OS is implemented based on microkernel structure? _____

进程的同步实验报告

操作系统 实验报告 哈尔滨工程大学 计算机科学与技术学院

一、实验概述 1. 实验名称 进程的同步 2. 实验目的 ⑴使用EOS的信号量,编程解决生产者 消费者问题,理解进程同步的意义。 ⑵调试跟踪EOS信号量的工作过程,理解进程同步的原理。 ⑶修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。 3. 实验类型 验证+设计 4. 实验内容 ⑴准备实验 ⑵使用EOS的信号量解决生产者-消费者问题 ⑶调试EOS信号量的工作过程 ①创建信号量 ②等待释放信号量 ③等待信号量(不阻塞) ④释放信号量(不唤醒) ⑤等待信号量(阻塞) ⑥释放信号量(唤醒) ⑷修改EOS的信号量算法 二、实验环境 WindowsXP + EOS集成实验环境 三、实验过程 1. 设计思路和流程图

图4-1.整体试验流程图

图4-2.Main 函数流程图、生产者消费、消费者流程图 2. 算法实现 3. 需要解决的问题及解答 (1). 思考在ps/semaphore.c 文件内的PsWaitForSemaphore 和PsReleaseSemaphore 函数中,为什么要使用原子操作?

答:在执行等待信号量和释放信号量的时候,是不允许cpu响应外部中断的,如果此时cpu响应了外部中断,会产生不可预料的结果,无法正常完成原子操作。 (2). 绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。 (3).P143生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢? 答:这是因为临界资源的限制。临界资源就像产品仓库,只有“产品仓库”空闲生产者才能生产东西,有权向里面放东西。所以它必须等到消费者,取走产品,“产品空间”(临界资源)空闲时,才继续生产14号产品。 (4). 根据本实验3.3.2节中设置断点和调试的方法,自己设计一个类似的调试方案来验证消费者线程在消费24号产品时会被阻塞,直到生产者线程生产了24号产品后,消费者线程才被唤醒并继续执行的过程。 答:可以按照下面的步骤进行调试 (1) 删除所有的断点。 (2) 按F5启动调试。OS Lab会首先弹出一个调试异常对话框。 (3) 在调试异常对话框中选择“是”,调试会中断。 (4) 在Consumer函数中等待Full信号量的代码行(第173行)WaitForSingleObject(FullSemaphoreHandle, INFINITE); 添加一个断点。 (5) 在“断点”窗口(按Alt+F9打开)中此断点的名称上点击右键。 (6) 在弹出的快捷菜单中选择“条件”。 (7) 在“断点条件”对话框(按F1获得帮助)的表达式编辑框中,输入表达式“i == 24”。 (8) 点击“断点条件”对话框中的“确定”按钮。 (9) 按F5继续调试。只有当消费者线程尝试消费24号产品时才会在该条件断点处中断。 4. 主要数据结构、实现代码及其说明 修改PsWaitForSemaphore函数 if (Semaphore->Count>0){ Semaphore->Count--; flag=STATUS_SUCCESS; }//如果信号量大于零,说明尚有资源,可以为线程分配 else flag=PspWait(&Semaphore->WaitListHead, Milliseconds); KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。 return flag; }//否则,说明资源数量不够,不能再为线程分配资源,因此要使线程等待 修改PsReleaseSemaphore函数 if (Semaphore->Count + ReleaseCount > Semaphore->MaximumCount) {

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

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

计算机科学与技术学院实验报告 实验题目:实验四、进程同步实验学号: 日期:20120409 班级:计基地12 姓名: 实验目的: 加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥 操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。了解 Linux 系统中 IPC 进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。 实验内容: 抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。请用以上介绍的 IPC 同步机制编程,实现该问题要求的功能。 硬件环境: 处理器:Intel? Core?i3-2350M CPU @ 2.30GHz ×4 图形:Intel? Sandybridge Mobile x86/MMX/SSE2 内存:4G 操作系统:32位 磁盘:20.1 GB 软件环境: ubuntu13.04 实验步骤: (1)新建定义了producer和consumer共用的IPC函数原型和变量的ipc.h文件。

(2)新建ipc.c文件,编写producer和consumer 共用的IPC的具体相应函数。 (3)新建Producer文件,首先定义producer 的一些行为,利用系统调用,建立共享内存区域,设定其长度并获取共享内存的首地址。然后设定生产者互斥与同步的信号灯,并为他们设置相应的初值。当有生产者进程在运行而其他生产者请求时,相应的信号灯就会阻止他,当共享内存区域已满时,信号等也会提示生产者不能再往共享内存中放入内容。 (4)新建Consumer文件,定义consumer的一些行为,利用系统调用来创建共享内存区域,并设定他的长度并获取共享内存的首地址。然后设定消费者互斥与同步的信号灯,并为他们设置相应的初值。当有消费进程在运行而其他消费者请求时,相应的信号灯就会阻止它,当共享内存区域已空时,信号等也会提示生产者不能再从共享内存中取出相应的内容。 运行的消费者应该与相应的生产者对应起来,只有这样运行结果才会正确。

进程间通信实验报告

进程间通信实验报告 班级:10网工三班学生姓名:谢昊天学号:1215134046 实验目的和要求: Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。 实验内容与分析设计: (1)消息的创建,发送和接收。 ①使用系统调用msgget (), msgsnd (), msgrev (), 及msgctl () 编制一长度为1k 的消息的发送和接收程序。 ②观察上面的程序,说明控制消息队列系统调用msgctl () 在此起什么作用? (2)共享存储区的创建、附接和段接。 使用系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序。(3)比较上述(1),(2)两种消息通信机制中数据传输的时间。 实验步骤与调试过程: 1.消息的创建,发送和接收: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)在SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER 。SERVER每接收到一个消息后显示一句“(server)received”。 (3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是 SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。 (4)父进程在 SERVER和 CLIENT均退出后结束。 2.共享存储区的创建,附接和断接: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1。作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER 每接收到一次数据后显示”(server)received”. (3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT退出. CLIENT每发送一次数据后显示”(client)sent”. (4)父进程在SERVER和CLIENT均退出后结束。 实验结果: 1.消息的创建,发送和接收: 由 Client 发送两条消息,然后Server接收一条消息。此后Client Server交替发送和接收消息。最后一次接收两条消息。Client 和Server 分别发送和接收了10条消息。message 的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象。在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理。

操作系统原理-进程调度实验报告

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

操作系统实验_实验1

广州大学学生实验报告 开课学院及实验室:计算机科学与工程实验室 2015年11月11日 实验课 操作系统成绩 程名称 实验项 进程管理与进程通信指导老师陈康民目名称 (***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***) 进程管理 (一)进程的创建实验 一、实验目的 1、掌握进程的概念,明确进程的含义 2、认识并了解并发执行的实质 二、实验内容 1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一 个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……', 父进程显示'parent ……',观察结果,分析原因。 三、实验步骤 1、编写一段程序,使用系统调用fork( )创建两个子进程。 代码: #include main( ) { int p1,p2; while((p1=fork( ))= = -1); /*创建子进程p1*/ if (p1= =0) putchar('b'); else { while((p2=fork( ))= = -1); /*创建子进程p2*/ if(p2= =0) putchar('c'); else putchar('a'); } } 运行结果:

bca,bac, abc ,……都有可能。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。 代码:#include main( ) { int p1,p2,i; while((p1=fork( ))= = -1); /*创建子进程p1*/ if (p1= =0) for(i=0;i<10;i++) printf("daughter %d\n",i); else { while((p2=fork( ))= = -1); /*创建子进程p2*/ if(p2= =0) for(i=0;i<10;i++) printf("son %d\n",i); else for(i=0;i<10;i++) printf("parent %d\n",i); } } 结果:

北邮高级操作系统期末试卷

2017,2015,2013北邮高级操作系统 试题 学号: 姓名: 成绩: 、分布式操作系统中的透明性主要是什么?其中那些透明性容易实现?哪些难实现????分? 难点: 、创建一个分布式数据库系统可提供有效的存取手段来操纵这些结点上的子数据库。 、不确定性,控制比较复杂,尤其是在资源管理上要附加许多协调操作—资源属于局部工作站,性能、可靠性对网络的依赖性强,安全保密——基础不好。用户掌握有许软件接口,相应的应用软件较少,需要大力开发。 、分布式互斥中集中式算法、分布式算法、令牌算法。分析一下其中那个算法比较实用,为什么????分? 集中式算法:集中式算法借鉴了集中式互斥算法的思想,在分布式系统

中,选出一个进程为协调者 ?通过科学的分析制定一套规则? 。协调者对所有的请求进行排队并根据一定的规则授予许可。协调者接受请求以后,检查临界区内的资源是否被其他进程占用。如果是,则它将当前请求进程插入到对应临界资源的请求队列中 否则,回复一个同意消息给请求进程,通知它可以访问该临界资源。该算法通俗易懂,既能够杜绝死锁、饥饿等现象发生,又能保证资源的互斥访问顺利进行。 但是它也有缺点,由于是集中式管理,所以一旦管理进程出现故障,则整个系统将处于瘫痪状态。因此,管理进程的性能完全决定了算法的效率,应用范围小,难以普及。 分布式算法:分布式算法中运用到广播请求通信,当进程想请求共享资源时,需要首先建立三个变量 准备进入临界区,实时时间和处理器号,并利用广播通信发送给正在运行的所有进程。该算法的核心思想如下 当进程想进入临界区时 要建立一个包括进入的临界区名字、处理器号和当前时间的消息 并把消息发送给所有其它进程。当进程接收到另一个进程的请求消息时 将分下面三种情况来区别对待 ?若接收者不在临界区中 也不想进入临界区 就向发送者发送 ?消息; ?若接收者已经在临界区内就不必回答 而是负责对请求消息排队; ?若接收者要进入临界区 但还没进入 它就会把接收的消息和它发送的消息的时间戳进行对比 取小的那个。如果接收的消息时间戳小 就发 ?消息 如果发送的消息时间戳小 那么接收者负责排列请求队列而不发送任何消息。当进程接收到允许消息时 它就进入临界区。从临界区退出时 向队列中的所有进程发送 ?消息 并将自己从队列中删除。该算法可以保证访问临界区的互斥性以及无死锁进程、无饥饿进程。但是这种算法有个严重的缺点是算法太复杂并且不健壮 任何一个进程崩溃都会影响到算法的正确性。二是令牌丢失 令牌算法:令牌算法中引入了令牌,所有的进程组成一个环模型,环中每个进程需要知道它的下一个位置的节点的名称。令牌在环上顺序传递,当

操作系统:进程调度实验报告

设计性实验报告 一、实验目的 1.在Linux下用C语言编程模拟优先级进程调度算法和时间片轮转进程调度算法。 2.为了清楚地观察每个进程的调度过程,每次调度程序应将各个进程的情况显示出来。 二、总体设计(设计原理、设计方案及流程等) 1、优先级进程调度算法 采用动态优先级进程调度算法,其基本思想是每次调度总是把处理机分配给优先级最高的进程,同时在运行过程中进程的优先级随着执行或等待的时间而降低或增加。 在该实验中每个进程用一个进程控制块( PCB)表示。进程控制块包含如下信息:进程号,进程名、优先数、需要运行时间、已用CPU时间、进程状态。进程号,名字,优先数,运行的时间,事先人为地指定。每个进程的状态可以是就绪,执行,阻塞或完成4种状态之一。 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。就绪队列中的进程在等待一个时间片后,优先级增1。如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时将进程的优先级减1,然后把它插入就绪队列等待CPU。 2、时间片轮转调度算法 采用简单时间片轮转调度算法,其基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。 三、实验步骤(包括主要步骤、代码分析等) 1.打开linux虚拟机,用vim编辑器打开代码进行修改和调整。用gcc编译器进行编译编译运行首先运行优先级算法,如图所示:

进程同步实验报告

实验三进程的同步 一、实验目的 1、了解进程同步和互斥的概念及实现方法; 2、更深一步的了解fork()的系统调用方式。 二、实验内容 1、预习操作系统进程同步的概念及实现方法。 2、编写一段源程序,用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。程序的输出是什么?分析原因。 3、阅读模拟火车站售票系统和实现进程的管道通信源代码,查阅有关进程创建、进程互斥、进程同步的系统功能调用或API,简要解释例程中用到的系统功能或API的用法,并编辑、编译、运行程序,记录程序的运行结果,尝试给出合理的解释。 4、(选做)修改问题2的代码,使得父子按顺序显示字符“a”;“b”、“c”编辑、编译、运行。记录程序运行结果。 三、设计思想 1、程序框架 (1)创建两个子进程:(2)售票系统:

(3)管道通信: 先创建子进程,然后对内容加锁,将输出语句存入缓存,并让子进程自己进入睡眠,等待别的进程将其唤醒,最后解锁;第二个子进程也执行这样的过程。父进程等待子进程后读内容并输出。 (4)修改程序(1):在子进程的输出语句前加上sleep()语句,即等待父进程执行完以后再输出。 2、用到的文件系统调用函数 (1)创建两个子进程:fork() (2)售票系统:DWORD WINAPI Fun1Proc(LPVOID lpPartameter); CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); CloseHandle(hThread1); (HANDLE)CreateMutex(NULL,FALSE,NULL); Sleep(4000)(sleep调用进程进入睡眠状态(封锁), 直到被唤醒); WaitForSingleObject(hMutex,INFINITE); ReleaseMutex(hMutex); (3)管道通信:pipe(fd),fd: int fd[2],其中: fd[0] 、fd[1]文件描述符(读、写); lockf( fd,function,byte)(fd: 文件描述符;function: 1: 锁定 0:解锁;byte: 锁定的字节数,0: 从当前位置到文件尾); write(fd,buf,byte)、read(fd,buf,byte) (fd: 文件描述符;buf : 信息传送的源(目标)地址;byte: 传送的字节数); sleep(5); exit(0); read(fd[0],s,50) (4)修改程序(1):fork(); sleep(); 四、调试过程 1、测试数据设计 (1)创建两个子进程:

北邮高级操作系统期末试卷

20仃,2015,2013北邮高级操作系统 试题 学号:姓名:成绩: 1、分布式操作系统中的透明性主要是什么?其中那些透明性容 易实现?哪些难实现?(20分) 难点: 1、创建一个分布式数据库系统可提供有效的存取手段来操纵这些结点上的子数据库。 2、不确定性,控制比较复杂,尤其是在资源管理上要附加许多协调操作一资源 属于局部工作站,性能、可靠性对网络的依赖性强,安全保密一一基础不好。用户掌握有许软件接口,相应的应用软件较少,需要大力开发。 2、分布式互斥中集中式算法、分布式算法、令牌算法。分析一下其 中那个算法比较实用,为什么?(20分) 集中式算法:集中式算法借鉴了集中式互斥算法的思想,在分布式系统中,选出一个进程为协调者(通过科学的分析制定一套规则)。协调者对所有的请求进行排队并根据一定的规则授予许可。协调者接受请求以后,检查临界区内的资源是否被其他进程占用。如果是,则它将当前请求进程插入到对应临界资源的请求队列中;否则,回复一个同意消息给请求进程,通知它可以访问该临界资源。该算法通俗易懂,既能够杜绝死锁、饥饿等现象发生,又能保证资源的互斥访问顺利进行。 但是它也有缺点,由于是集中式管理,所以一旦管理进程出现故障,则整个系统将处于 瘫痪状态。因此,管理进程的性能完全决定了算法的效率,应用范围小,难以普及。

分布式算法:分布式算法中运用到广播请求通信,当进程想请求共享资源时,需要首先建立三个变量:准备进入临界区,实时时间和处理器号,并利用广播通信发送给正在运行的所有进程。该算法的核心思想如下:当进程想进入临界区时,要建立一个包括进入的临界区名字、处理器号和当前时间的消息,并把消息发送给所有其它进程。当进程接收到另一个进程的请求消息时,将分下面三种情况来区别对待:1)若接收者不在临界区中,也不想进入临界区,就向发送者发送0K消息;2)若接收者已经在临界区内就不必回答,而是负责对请求消息排队;3)若接收者要进入临界区,但还没进入,它就会把接收的消息和它发送的消息的时间戳进行对比,取小的那个。如果接收的消息时间戳小,就发0K消息,如果发送的消息时间戳小,那么接收者负责排列请求队列而不发送任何消息。当进程接收到允许消息时,它就进入临界区。从临界区退出时,向队列中的所有进程发送0K消息,并将自己从队列中删除。该算法可以保证访问临界区 的互斥性以及无死锁进程、无饥饿进程。但是这种算法有个严重的缺点是算法太 二是令牌丢失 复杂并且不健壮,任何一个进程崩溃都会影响到算法的正确性。 令牌算法:令牌算法中引入了令牌,所有的进程组成一个环模型,环中每个进程需要知道它的下一个位置的节点的名称。令牌在环上顺序传递,当某个进程拥有令牌时就表明可以访问临界区。当请求进程没有令牌时,算法需要N发送任何消息。如果得到令牌的进程不打算进入临界区,它只是简单地将令牌传送给它后面的进程。当每个进程都需要进入临界区时,令牌在环上的传递速度最慢;相反,当没有进程想要进入临界区时,令牌在环上的传递速度最快。 (该算法的正确性是显而易见的,但是也存在一些问题,比如说,当令牌丢失时,需要重新生成。可是如何检测令牌丢失又是一个困难的问题。还有,如果环中的一个进程崩溃,那么环 的连贯性就遭到破坏,算法也就会出现麻烦。) 综上所述,基于令牌的算法在排除了令牌丢失和进程故障等问题之后,在今后的分布式系统中,能有更好的应用。

相关文档
最新文档