何洲操作系统课程设计实验报告

武汉工程大学

计算机科学与工程学院

综合设计报告

设计名称:          操作系统综合设计           

设计题目:              线程同步               

学生学号:             1205080205              

专业班级:          20##计算机工程02           

学生姓名:               何洲                  

学生成绩:                                     

指导教师(职称):        章瑾(副教授)       

完成时间:   1568  156 12   

武汉工程大学计算机科学与工程学院   制

说明:

1、报告中的第一、二、三项由指导教师在综合设计开始前填写并发给每个学生;四、五两项(中英文摘要)由学生在完成综合设计后填写。

2、学生成绩由指导教师根据学生的设计情况给出各项分值及总评成绩。

3、指导教师评语一栏由指导教师就学生在整个综合设计期间的表现、设计完成情况、报告的质量及答辩等方面,给出客观、全面的评价。

4、所有学生必须参加综合设计的答辩环节。凡不参加答辩者,其成绩一律按不及格处理。答辩小组成员应由2人及以上教师组成。

5、报告正文字数一般应不少于5000字,也可由指导教师根据本门综合设计的情况另行规定。

6、平时表现成绩低于6分的学生,其综合设计成绩按不及格处理。

7、此表格式为武汉工程大学计算机科学与工程学院提供的基本格式(适用于学院各类综合设计),各教研室可根据本门综合设计的特点及内容做适当的调整,并上报学院批准。

答辩记录表

成绩评定表

学生姓名:何洲  学号:   1205080205  班级: 20##计算机工程02                


目 录

摘  要.................................................................... I

Abstract................................................................. II

第一章 绪论............................................................... 1

1.1课程设计的背景........................................................ 1

1.2课程设计的目的........................................................ 1

1.3课程设计的要求........................................................ 1

1.4应解决的问题.......................................................... 1

第二章 设计简介及设计方案论述............................................. 2

2.1总体设计.............................................................. 2

2.2设计原理.............................................................. 2

2.3流程图................................................................ 2

第三章  详细设计.......................................................... 4

3.1界面设计.............................................................. 4

3.2功能设计.............................................................. 4

3.3信号量和P、V操作..................................................... 5

3.4设置生产消费速度模块设计.............................................. 5

第四章  设计结果及分析.................................................... 6

4.1 功能测试.............................................................. 6

4.2课程设计中遇到的问题.................................................. 7

总   结................................................................... 8

致   谢................................................................... 9

参考文献................................................................. 10

附录  主要程序代码....................................................... 11

摘  要

生产者—消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。在同一地址进程空间内执行的两个线程,生产者生产物品,然后将生产出的物品放在一个空缓冲区内供消费者进程消费。消费者从缓冲区中获得物品,然后释放缓冲区。当生产者生产物品时,消费者不能消费物品。而当消费者正在消费物品的时候,生产者亦不能生产物品。当生产者生产物品的时候如果缓冲区已满,就必须等待消费者消费物品释放缓冲区后才能继续生产。而当消费者在消费时,若缓冲区内没有物品,则阻塞并唤醒生产者生产物品才可进行消费。本文论述了在eclipse开发环境下,使用java语言模拟实现生产者—消费者问题。生产者和消费者的数目都为1,两个线程同步,生产者生产完一个物品后消费者便消费一个物品,同时可以设置生产者的生产速度和消费者的消费速度。该程序使学生对操作系统的工作机制有了基本了解,熟悉Windows中的线程及进程的创建,掌握利用Windows中的同步机制实现线程同步。培养学生的抽象思维能力、逻辑推理能力和形式化思维方法,增强分析问题和解决问题的能力。在程序的设计开发过程中,首先对程序的要求进行了仔细的分析,做出整体的设计。然后再对每一个部分进行更具体的分析与设计,接着着手程序的编码、运行、调试。经过一个星期的的设计后,程序全部完成,达到课程设计的要求。

关键词:生产者—消费者问题;JAVA语言;信号量;线程

Abstract

Producer consumer problem is a classical process synchronization problem, the problem was first proposed by Dijkstra, in order to demonstrate the signal mechanism he proposed. In the same address process space within the two thread, producer goods, and then the production of goods placed in an empty buffer for the process of consumer spending. Consumers get the goods from the buffer and then release the buffer. When the producer produces goods, the consumer can't consume the goods. While consumers are consuming goods, producers can not produce goods. When the producer goods if the buffer is full, it must wait for the consumer goods release buffer to continue to produce. When consumers consume, if there is no item in the buffer zone, then plug and wake the producer to produce goods to consume. In this paper, the producer consumer problem is realized by using java language in eclipse development environment.. The number of producers and consumers are all 1, two thread synchronization, producers of the production of finished goods consumers consumption goods, also can set producers of the production rate and consumer consumption rate. The program makes the students have a basic understanding of the operating mechanism of the operating system, familiar with the creation of the thread and process in Windows, master the synchronization mechanism of the synchronization in Windows. To cultivate the students' abstract thinking ability, logical reasoning ability and formal thinking method, and strengthen the ability to analyze and solve problems. In the design and development of the program, the requirements of the procedure is analyzed carefully, and the design of the whole is made.. Then, it will analyze and design more concretely every part, then proceed the coding, running and debugging of the program.. After a week of design, the program is all completed, meet the requirements of the course design.

Keywords:Producer—consumer problem; JAVA language; signal; quantity thread


第一章 绪论

1.1课程设计的背景

在多道程序的环境下,进程之间的同步问题非常重要,我们在学习了操作系统这门课程后,为了进一步了解多线程之间的同步和互斥问题,老师给我们布置了生产者与消费者的问题,帮助我们了解线程如何竞争,如何避免死锁的问题。

1.2课程设计的目的

在我们所学的操作系统这门课程中,关于进程同步的问题进行了一定的描述和探讨,介绍了几个比较经典的算法,但是还需要我们在实践中去实现完善并且熟练的掌握并运用。在本次试验中,我们需要运用信号量解决进程同步问题的方法,进而学会运用进程的同步于互斥解决生产者与消费者的冲突的问题。

1.3课程设计的要求

该课程设计要求运用基于单缓冲区和多缓冲区的生产者与消费者的多种实现机制。

首先我们是基于Java 语言进行编写,必须拥有一个界面框,其中包含了四个文本框和三个按钮和四个标签,其中两个文本框用来读取设计的生产者与消费者的速度,及睡眠时间,睡眠时间越大表示速度越慢。还有两个文本框用来显示设置速度之后的消费者与生产者的速度。其中一个按钮表示设置生产者与消费者速度,一个表示启动线程,最后一个表示关闭该程序。其中包括两个线程消费者与生产者,要求运用信号量解决进程同步的问题。

1.4应解决的问题

首先我们要通过查阅资料了解生产者与消费者的问题的核心是什么,通过查阅资料

我们可以了解到他们之间的问题其实就是线程同步问题,而现在线程同步的问题一般都是采用信号量或者加锁机制。在本次试验中我们采用的是信号量方法。即生产者线程当缓冲区已满时放弃自己的执行权,进入等待状态,并通知消费者线程执行。消费者线程当缓冲区已空时放弃自己的执行权,进入等待状态,并通知生产者线程执行。这样一来就保持了线程的同步,并避免了线程间互相等待而进入死锁状态。

第二章 设计简介及设计方案论述

2.1总体设计

将程序界面分成4块,分别为生产者线程、消费者线程、生产消费状态和按钮与文本框。在生产者线程中显示生产者的生产状态,生产了那些产品;在消费者线程中显示消费者的消费状态,消费了那些产品;在生产消费状态中反映的是生产者线程与消费者线程的状态,线程休眠和线程唤醒以及缓冲区是否有资源;按钮与文本框则是设置生产、消费的速度以及启动线程。

在生产者和消费者速度对应的文本框中输入生产消费的速度则可以对其进行设置,然后点击启动按钮,程序开始运行,显示生产者线程、消费者线程以及生产消费的状态。

在这次课程设计中,生产者线程与消费者线程是同步的。即生产者每生产一个产品,消费者就消费对应的产品。生产者和消费者的数目为1,总共生产10个产品。

2.2设计原理

线程同步是指几个线程相互合作,一个线程到达某个点后,除非另一个进程已经完成某些操作,否则就不得不停下来,等待这些操作的结束,这就是进程同步的概念。

生产者—消费者问题是一种同步问题的抽象描述。计算机系统中的每个线程都可以消费或生产某类资源,当系统中某一线程使用某一资源时,可以看作是消耗,且该线程称为消费者。而当某个线程释放资源时,则它就相当一个生产者。

通过一个有界缓冲区把生产者和消费者联系起来。假定生产者和消费者是相互等效的,两个线程同步进行,生产者没生产一个产品,消费者便消费一个产品。若缓冲区内有产品而消费者未消费,则生产者休眠,并唤醒消费者消费;而当缓冲区内没有产品可消费时,消费者休眠,并唤醒生产者生产。

在生产者—消费者问题中,信号灯具有两种功能。首先,它是跟踪资源的生产和消费计数器;其次,它是协调资源的生产者和消费者之间的同步器。消费者通过在信号灯上做P操作来表示消耗资源,而生产者通过在同一信号灯上做V操作来表示生产资源。

2.3流程图

程序流程图如图2.1所示。首先创建生产者线程,然后输入产品到缓冲区,若消费者正在消费则阻塞。否则生产者等待唤醒消费者消费产品。当缓冲区为空的时候,消费者线程阻塞,并唤醒生产者生产产品。

 

第三章  详细设计

3.1界面设计

定义一个JFrame窗体,大小为(1100,300),将该窗体分成4个面板,分别是3个 ScrollPane和1个JPanel,采用网格布局一行四列。JPnel面板用来聚集按钮和文本框组件。ScrollPane面板是带滚动条的面板,它也是一种容器,但是ScrollPane只能放置一个组件。3个ScrollPane分别用来显示生产者线程、消费者线程和生产消费状态。JPanel面板上有两个按钮分别是启动按钮和设置生产消费速度以及两个文本框,在两个文本框中分别输入生产速度和消费速度,然后点击设置生产消费速度按钮即可对生产消费速度进行设置,然后点击启动按钮就,程序开始运行。

3.2功能设计

程序的整体功能如图3.1所示。首先在文本框输入生产消费的速度,然后点击设置生产消费速度按钮完成设置。接着点击启动按钮,程序开始运行。

 

图 3.1 功能设计图

3.3信号量和P、V操作

为了能让多个进程通过特殊变量展开交互,一个进程在某一关键点上被迫停止执行直至收到对应的特殊变量,通过这一措施,来达到复杂进程间的交互,这种特殊变量就是信号量。为了能够用信号量传送信号,进程可用P、V两个特殊操作来发送和接收信号,如果协作进程的相应信号仍未送到,则进程被挂起直至信号达到为止。

P、V操作的实现,是本次课程设计的基础,也是一个重点。。即充分的借助于JAVA虚拟机提供的两个与线程有关的最重要的两个函数,即wait()和notify()。我们都知道,实现P、V操作的重点是如何将进程阻塞在相应的阻塞队列,以及如何唤醒相应的阻塞进程,而不会出现错误。要实现这一点,有一定的难度。前期,我做过尝试,但最终以失败而告终。最后,我们找到了JAVA虚拟机提供两个函数来实现我们的目的。函数如下:

wait()  执行该方法的线程释放对象的锁,Java虚拟机把该线程放到该对象的等待池中。

Notify()  执行该方法的线程唤醒在该对象等待池中等待的一个线程。

因为java是面向对象的一门编程语言,一切属性与方法都与对象绑定,而这一点正是我们要解决的难点:如何将进程阻塞在相应的阻塞队列,以及如何唤醒相应的阻塞进程。可以说,我们是把这个难题交给了java虚拟机来处理。

3.4设置生产消费速度模块设计

在Producer和Consumer类中分别设置一个私有属性n,n描述的是线程进行休眠的时间。在JPanel面板上添加两个文本框分别用来输出Producer线程和Consumer线程的休眠时间,由于休眠时间最长,速度越慢,因此若n的值越大,生产或消费的速度越慢。

同时在JPanel面板上创建设置生产消费速度的按钮,为按钮组件添加动作监听器。当在文本框内输入n的值后,点击按钮,将触发事件。调用getText()方法将文本框中的内容读取出来,并转化为整形。然后调用Producer和Consumer的setN()方法,完成对n的设置。

第四章  设计结果及分析

4.1 功能测试

1、程序开始界面如图4.1所示

图4.1 开始界面

2、设置生产者速度为1000,设置消费者速度为100。由图4.2测试用例1可知,消费者的消费速度快于生产者的生产速度,消费者频繁等待生产者生产。

图4.2 测试用例1

3、设置生产者速度为100,设置消费者速度为1000。由图4-3测试用例2可知,消费者的消费速度慢于生产者的生产速度,生产者频繁等待消费者消费。

图4.3 测试用例2

4、设置生产者速度为500,设置消费者速度为500。由图4.4测试用例3可知,消费者的消费速度等于生产者的生产速度,没有发生等待。

图4.4 测试用例3

4.2课程设计中遇到的问题

在本次课程设计中遇到的最大的问题就是实现设置生产消费速度这一模块时,一开始并不知道如何下手。后来通过网上查资料、书本上查资料,找到的解决该问题的方法。但是,在接下来的工作中又遇到各种各样的问题,比如设置后并没有起任何的作用、程序抛出异常等等。不过最终还是较好的解决了这一问题。

总   结

本次课程设计通过模拟计算机操作系统中经典的“生产者—消费者问题”,巩固了我在操作系统原理上所学的知识,加深了对操作系统中进程同步和互斥等问题的理解,完成了多线程同步方法解决生产者—消费者问题全部过程,结果满足设计要求。

在编写程序的时候我们不可能一次就成功,往往一个图形就要修改甚至是十几次才能得到预期的结果。因此在编写程序的时候一定不能急躁,要耐心的检测输入的数据和输出的结果,在没达到预期目的的情况下,要及时修改数据进行下一次检测,只有这样才能成功的编写出需要的程序。

编写程序是一个长期的过程,因此不能急躁,要坐得住。由于学校并没有开设Java课程,我对Java的知识都是通过自学获得的,导致很多知识点掌握的并不是很全面。所以我找出了以前的笔记,花了半天时间去重新学习和理解。对操作系统有关生产者—消费者问题的含义也有点模糊,我花了几个小时的时候看教材,在网上查询相关资料,才开始编程。刚开始对这次课程设计一筹莫展,于是和一些同学进行了很长时间的讨论,但是也没有什么好的效果。编写程序有的时候需要的就是灵感,因此当有灵感的时候就要开始做,而不能等,必须早灵感未消失前付诸行动,所以导致我长时间呆在电脑前完成这次课程设计。虽然很累,但是觉得值得。

经历了进一个星期的时候,我基本上完成了它,从中让我得到了好多的东西。首先,这个过程锻炼了我的意志,还让我对线程的控制和编写过程有了一个更深层次的认识和理解。其次,我现在对windows操作系统执行流程有了一个透明的认识,同时也让我对它更有亲切感。总之,这次作业让我受益匪浅。

致   谢

这次的课程设计又让我得到了更多锻炼,巩固了我所学到知识,从中我受益匪浅,而这一切离不开老师同学的帮助。感谢章谨老师给我们这次课程设计出题,感谢章谨老师对我们完成课程设计进行指导。感谢在编程过程中给我帮助的同学。

参考文献

[1]Bruce Eckel.Java编程思想[M].北京 机械工业出版社,2014.11

[2]李春葆主编.数据结构教程[M].北京 清华大学出版社,2013.1

[3]汤子瀛等.计算机操作系统[M].西安 西安电子科技大学出版社,2004.5

[4]梁勇.Java 语言程序设计[M].北京 机械工业出版社,2011.5

[5]吕国英主编.算法分析与设计[M].北京 清华大学出版社,2009.1

[6]明日科技编著.Java从入门到精通[M].北京 高等教育出版社,2012.9

附录  主要程序代码

package shengchan;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

//窗口类

class window extends JFrame {

       public JFrame jf;

       public JPanel jp3;

       public ScrollPane sp1, sp2, sp3;

       public Container c;

       window() {

              jf = new JFrame();

              jp3 = new JPanel();

              sp1 = new ScrollPane();

              sp2 = new ScrollPane();

              sp3 = new ScrollPane();

              c = getContentPane();

              c.setLayout(new GridLayout(1,4,5, 10));

              jf.add(c);

              c.add(sp1);

              c.add(sp2);

              c.add(sp3);

              c.add(jp3);

              jf.setSize(1100, 300);

              jf.setVisible(true);

              jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       }

}

class Data {

       private int u;

       private boolean available = false;

       public JTextArea jt = new JTextArea("生产消费状态\n\n");

       public synchronized int get() {

              while (available == false) {

                     try {

                            wait();

                     } catch (InterruptedException e) {

                     }

                     jt.append( " 没有资源,消费者等待……\n");

              }

              available = false;

              notifyAll();

              jt.append(" 正在唤醒生产者生产……\n");

              return u;

       }

       public synchronized void put(int value) {

              while (available == true) {

                     try {

                            wait();

                     } catch (InterruptedException e) {

                     }

                     jt.append(" 已有资源,生产者等待……\n");

              }

              u = value;

              available = true;

              notifyAll();

              jt.append(" 正在唤醒消费者消费……\n");

       }

}

// 生产者类

class Producer extends Thread {

       private int n;

       private Data data;

       public String jieguo[] = new String[11];

       public JTextArea jt = new JTextArea("\t生产者线程\n\n");

      

       public Producer(){}

       public Producer(int n, Data data) {

              super();

              this.n = n;

              this.data = data;

       }

       public Producer(Data data) {

              super();

              this.data = data;

       }

       public int getN() {

              return n;

       }

       public void setN(int n) {

              this.n = n;

       }

       public void run() {

              for (int i = 1; i < 11; i++) {

                     data.put(i);

                     jieguo[i] = " 生产者第" + i + "次生产" + "  生产者的生产数据:" + i + "\n";

                     jt.append(jieguo[i]);

                     try {

                            sleep(this.getN());

                     } catch (InterruptedException e) {

                           

                     }

              }

       }

}

class Consumer extends Thread {

       private int n;

       private Data data;

       public String jieguo[] = new String[11];

       public JTextArea jt = new JTextArea("\t消费者线程\n\n");

      

       public Consumer(){}

       public Consumer(int n, Data data) {

              super();

              this.n = n;

              this.data = data;

       }

       public Consumer(Data data) {

              super();

              this.data = data;

       }

       public int getN() {

              return n;

       }

       public void setN(int n) {

              this.n = n;

       }

       public void run() {

              int value = 0;

              for (int i = 1; i < 11; i++) {

                     value = data.get();

                     jieguo[i] =  " 消费者第" + i + "次消费" + "  消费者获得的生产数据:" + value

                                   + "\n";

                     jt.append(jieguo[i]);

                     try {

                            sleep(this.getN());

                     } catch (InterruptedException e) {

                           

                     }

              }

       }

}

// 程序入口

public class PCmx {

       public static JTextField jt = null;

       public static JTextField jt1 = null;

       public static void main(String[] args) {

              window win = new window();

              BHandler h = new BHandler();

              BHandler1 h1 = new BHandler1();

              JButton jb = new JButton("启动");

              JButton jb1 = new JButton("设置生产和消费速度");

              jt = new JTextField("生产者速度",20);

              jt1 = new JTextField("消费者速度",20);

              win.jf.setTitle("\t生产者与消费者");

              jb.addActionListener(h);

              jb1.addActionListener(h1);

              win.jp3.add(jb);

              win.jp3.add(jb1);

              win.jp3.add(jt);

              win.jp3.add(jt1);

              jb.setBounds(50, 100, 100,150);

              h.winadd(win.jf, win.sp1, win.sp2, win.sp3, win.jp3);

       }

}

class BHandler1 implements ActionListener{

       public static Producer p = null;

       public static Consumer c = null;

       public static Data s = null;

       public void actionPerformed(ActionEvent e) {

              s = new Data();

              p = new Producer(s);

              c = new Consumer(s);

              p.setN(Integer.parseInt(PCmx.jt.getText()));

              c.setN(Integer.parseInt(PCmx.jt1.getText()));

       }

}

class BHandler implements ActionListener {

       private ScrollPane sp1, sp2, sp3;

       private JPanel jp1;

       private JFrame jf;

       JTextArea jt1 = new JTextArea();

       JTextArea jt2 = new JTextArea();

       public void actionPerformed(ActionEvent e) {

              jf.setTitle("\t生产者与消费者");

//            Producer p = new Producer(s);

//            Consumer c = new Consumer(s);

              sp1.add(BHandler1.p.jt);

              sp2.add(BHandler1.c.jt);

              sp3.add(BHandler1.s.jt);

              BHandler1.p.start();

              BHandler1.c.start();

       }

       public void winadd(JFrame jff, ScrollPane s1, ScrollPane s2, ScrollPane s3,

                     JPanel j1) {

              jf = jff;

              sp1 = s1;

              sp2 = s2;

              sp3 = s3;

              jp1 = j1;

       }

}

相关推荐