一、实验目的和要求

要求了解操作系统的基本原理及基本概念,掌握实现各原理的算法,能结合实际开发工具模拟演示课程中涉及的算法,以达到深入掌握操作系统理论的目的。要求学生上机之前充分准备,给出算法的设计流程和详细代码;认真做实验,要求给出调试通过的可运行程序;认真解答思考题中的问题,记录实验中遇到的问题和解决方法;独立编写实验报告。

掌握并发进程中同步与互斥的机制,基于线程的编程技术开发类似生产者—消费者问题的演示程序。

二、实验方法与步骤(需求分析、算法设计思路、流程图等)

1.进程同步和互斥的概念:

进程同步的概念:把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。具有同步关系的一组并发进程称为合作进程,合作进程间互相发送的信号称为消息或事件。

进程互斥的概念:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥。也就是说,一个进程正在访问临界资源,另一个要访问该资源的进程必须等待。

我们把一个时间段内只允许一个进程使用的资源称为临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。对临界资源的访问,必须互斥地进行。互斥,亦称间接制约关系。

进程同步是进程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

信号量实现方式:通过设置一个表示资源个数的信号量 S,通过对信号量 S 的 P 和 V 操作来实现进程的的互斥。P V 操作是操作系统的原语。

P 操作首先减少信号量,表示有一个进程将占用或等待资源,然后检测 S 是否小于 0,如果小于 0 则阻塞,如果大于 0 则占有资源进行执行。

V 操作是和 P 操作相反的操作,首先增加信号量,表示占用或等待资源的进程减少了 1个。然后检测 S 是否小于 0,如果小于 0 则唤醒等待使用 S 资源的其它进程。

2.临界资源的互斥访问的四个部分:

进入区,临界区,退出区,剩余区。

3.为实现进程互斥,所有的同步机制应该遵循四大准则:

1.空闲让进。临界区空闲时,可允许一请求进入临界区的进程立即进入临界区;

2.忙则等待。当己有进程进入临界区时,其他试图进入临界区的进程必须等待;

3.有限等待。对请求访问的进程,应保证能在有限时间内进入临界区;

4. 让权等待。当进程不能进入临界区时,应立即释放处理,防止进程忙等待。

三、实验原始纪录(源程序、数据结构等)

1.同步

#include

typedef int semaphore;

struct process

{

};

typedef struct

{

int value; //资源个数

struct process *L; //阻塞队列

}ss;

void P(int *n)

{

(*n)–; //申请一个资源

printf(“apply a resource! n=%d\n”,(*n));

if((*n)<0)printf("no resources available,block the process!\n");

}

void V(int *n)

{

(*n)++; //释放一个资源

printf(“release a resource! n=%d\n”,(*n));

if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");

}

void P1(int *n)

{

printf(“process P1!\n”);

printf(“Access code.\n”);

V(n);

}

void P2(int *n)

{

printf(“process P2!\n”);

P(n);

printf(“Access code.\n”);

}

int main()

{

semaphore n=0;

P1(&n);

P2(&n);

return 0;

}

2.互斥

#include

typedef int semaphore;

struct process

{

};

typedef struct

{

int value; //资源个数

struct process *L;

}ss;

void P(int *n)

{

(*n)–; //申请一个资源

printf(“apply a resource! n=%d\n”,(*n));

if((*n)<0)printf("no resources available,block the process!\n");

}

void V(int *n)

{

(*n)++; //释放一个资源

printf(“release a resource! n=%d\n”,(*n));

if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");

}

void P1(int *n)

{

printf(“process P1!\n”);

P(n);

printf(“Access critical code.\n”);

V(n);

}

void P2(int *n)

{

printf(“process P2!\n”);

P(n);

printf(“Access critical code.\n”);

V(n);

}

int main()

{

semaphore n=1;

P1(&n);

P2(&n);

return 0;

}

四、实验结果及分析(计算过程与结果、数据曲线、图表等)

同步

互斥

以上进程的同步与互斥模拟算法符合其性质和概念,实验这个程序编写正确。

五、实验改进与思考

今天我们做了操作系统实验,其主题为“多线程编程解决进程间同步和互斥问题”。故将实验分为同步和互斥两个部分。

在实验之前,我对这个知识还处于一知半解的状态,在实验过后,我明白了进程同步是进程之间直接的制约关系,它们是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。而且当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

通过一次次的实验,我发现我对计算机有了新的认识,以前只明白玩游戏、娱乐和简单的应用。经过这次的实验,我了解到,要真真正正的掌握计算机程序编写还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技,我喜欢高端便捷的生活。我期望我能做计算机这个万能机器人的主人而不是奴隶,而不断的去进行实验会使我的思想、技能去上一个台阶!