多进程同步橘子苹果问题完整报告(附源代码).doc

上传人:wux****ua 文档编号:9390631 上传时间:2020-04-05 格式:DOC 页数:42 大小:253KB
返回 下载 相关 举报
多进程同步橘子苹果问题完整报告(附源代码).doc_第1页
第1页 / 共42页
多进程同步橘子苹果问题完整报告(附源代码).doc_第2页
第2页 / 共42页
多进程同步橘子苹果问题完整报告(附源代码).doc_第3页
第3页 / 共42页
点击查看更多>>
资源描述
一、 课程设计目的本次实验进行操作系统课程设计的主要任务是模拟生产者和消费者的一个衍生,即实现“橘子-苹果问题”。这个问题中有两个生产者,分别生产苹果核橘子,有两个消费者,分别消费橘子和苹果。同时,因为两个生产者和两个消费者对同一个缓冲区进行操作,所以应互斥的访问缓冲区以保证程序的正确性。本次实验的目的就是加深各个进程正确有效的对资源的访问,即同步和互斥。同时掌握信号量在互斥访问中的使用。掌握生产者和消费者问题的流程和实现方法。同时提高编程的能力、对问题的解决能力及查阅文档的能力。二、 课程设计内容与要求1、通过研究Linux的进程同步机制和信号量,实现特殊的生产者与消费者问题的并发控制。2、说明:有两类生产者,一类负责生产桔子,一类负责生产苹果;有两类消费者,一类负责消费桔子,一类负责消费苹果;他们共享一个有20个存储单元的有界缓冲区,每个存储单元只能放入一种产品(桔子/苹果)。3、设计要求:1) 二类生产者与二类消费者数目均为20,即20个生产者负责生产桔子,20个生产者负责生产苹果;20个消费者负责消费桔子,20个消费者负责消费苹果2) 二类生产者的生产速度与二类消费者的消费速度均可独立在程序界面调节,在运行中,该值调整后立即生效3) 多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码,同时需要考虑算法的效率性4) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前生产者与消费者的指针位置,以及生产者和消费者线程标识符5) 采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓冲区的状态三、 系统分析与设计1、系统分析1.此次任务是实现特殊生产者和消费者的演示程序,所需要处理的信息是生产者和消费者的个数,生产苹果、橘子和消费苹果、橘子的速度控制,缓冲区中橘子和苹果的个数和当前生产、消费指针的位置。2.程序中需要处理缓冲区的动态显示、生产者和消费者的速度可以调节,生产者和消费者个数可以改变。为了实现界面的友好性,应该对用户标明清楚各个模块的作用。同时实时的对程序进行暂停和停止。演示程序中用图形显示的方法描述缓冲区的使用情况,即当前缓冲区有多少个苹果和橘子,还有生产和消费者的指针。3.系统对外的界面如下:可以调节橘子和苹果的生产速度和消费苹果和橘子的速度,在文本框中输入相应的速度,再按下修改按键即可实现速度的实时调节。在苹果生产者、橘子生产者、苹果消费者、橘子消费者中实现对个数按钮的按下即可动态实时的调节生产者和消费者的个数的调节。在界面的最下面点击开始按钮,程序开始运行,暂停按钮使程序暂停挂起,再点击则可以继续运行。停止按钮实现此次程序的演示结束。4.此次使用java平台实现,保证了程序在各种机器的运行,只需要事前建立java的运行环境即可,便于程序的移植5.系统界面如下:动态显示区程序速度控制区生产者和消费者数字调节开始、暂停、终止按键区2、系统设计:2.1、模块设计:系统主模块主界面模块生产者控制模块消费者控制模块块有界缓冲区控制模块人工智能模块主界面模块绘图模块动态进度条生产者数目调节消费者数目调节生产者速度调节消费者速度调节2.2、数据结构说明:1.缓冲区的数据结构:双端队列说明:左端放置生产苹果的指针,右端放置生产橘子的指针。缓冲区苹果指针橘子指针2.缓冲区操作的类图,实现对缓冲区的实际操作缓冲区MyStorage生产苹 果increaseapple()生产橘子increaseorange()消费苹果decreaseapple()消费橘子decreaseorange()缓冲区状态isFull互斥信号量mutex同步信号量emptyfull苹果指针pointapple橘子指针pointorange2.3、算法流程图:1.生产苹果算法申请空缓冲区信号量empty大于0pointapple = pointapple+1isFullapplepoint = truePoolpointapple = 1打印缓冲区状态apple=apple+1 full=full+1释放缓冲区线程阻塞NY2.消费苹果算法申请空缓冲区 full=full+1信号量full大于0pointapple = pointapple-1isFullapplepoint = falsePoolpointapple = 0打印缓冲区状态apple=apple-1empty=empty+1释放缓冲区线程阻塞YN3.绘图算法i = i+1i 20?pooli=0pooli=1填充红色填充黄色画矩形画指针i =-14.生产苹果者人工智能算法(生产橘子人工智能相似)进入缓冲区缓冲区产品数=16增加苹果消费者,减少苹果生产者,增加橘子生产者生产苹果苹果=12拒绝生产请求增加苹果消费者退出缓冲区NYNYN5.苹果消费者人工智能算法(生产橘子算法类似)进入缓冲区缓冲区产品数=4苹果个数2消费苹果增加苹果生产者减少苹果消费者增加橘子生产者增加橘子生产者减少橘子消费者增加苹果生产者退出缓冲区YNYN橘子数2增加橘子生产者减少橘子消费者增加苹果生产者苹果数2增加苹果生产者减少苹果消费者增加橘子生产者YYNN四、系统测试与调试分析1、系统测试(1)因为当苹果生产者在缓冲区满了以后自动阻塞,需要苹果消费者唤醒,所以需要测试唤醒的实现是否正常。测试说明测试名称用多进程同步方法演示“桔子-苹果”问题测试目的验证苹果生产者能被苹果消费者唤醒测试技术单元测试测试方法黑盒测试法测试用例测试内容当生产者生产满缓冲区后,开始增加消费者,唤醒生产者测试步骤增加苹果生产者等待缓冲区被用完增加苹果消费者测试数据增加苹果生产者到3缓冲区苹果数量20缓冲区空闲位为0苹果消费者增加到4预期结果缓冲区开始增加苹果缓冲区满 苹果生产者阻塞苹果生产者被唤醒,缓冲区中苹果数量减少测试结果与预期相符与预期相符与预期相符(2)因为当苹果生产者在缓冲区满了以后自动阻塞,需要苹果消费者唤醒,所以需要测试唤醒的实现是否正常。测试说明测试名称用多进程同步方法演示“桔子-苹果”问题测试目的验证多个苹果橘子生产者和苹果、橘子消费者互斥操作缓冲区测试技术单元测试测试方法黑盒测试法测试用例测试内容缓冲区为空,消费者阻塞时,生产者唤醒消费者测试步骤开始生产产品,缓冲区为空 空闲位20开始消费产品,终止生产线程开始增加生产者减少消费者测试数据橘子生产者数量5苹果生产者数量5苹果生产者减少到0橘子生产者减少到0增加橘子消费者到5增加苹果消费者到5增加苹果生产者到5增加橘子生产者到5减少橘子消费者到2减少苹果消费者到2预期结果缓冲区内产品数量每次减少10个消费完成产品,消费者阻塞唤醒消费者,缓冲区中产品增加测试结果与预期相符与预期相符与预期相符(3)测试生产者和消费者的速度是否可以调节测试说明测试名称用多进程同步方法演示“桔子-苹果”问题测试目的苹果、橘子生产者和苹果、橘子消费者速度可以调节测试技术单元测试测试方法黑盒测试法测试用例测试内容调节生产者和消费者速度测试步骤开始程序运行输入生产者、消费者速度值点击修改按钮测试数据苹果、橘子生产者速度2000苹果、橘子消费者速度2000生产者的速度值 1000消费者速度值1000点击修改预期结果缓冲区开始被操作界面文本框中显示速度值生产者、消费者速度变化到1000测试结果与预期相符与预期相符与预期相符(4)实现了人工智能操作:即系统自动保持生产者和消费者的相对平衡,测试功能的正确实现测试说明测试名称用多进程同步方法演示“桔子-苹果”问题测试目的测试编写的人工智能是否实现测试技术单元测试测试方法黑盒测试法测试用例测试内容自动维持缓冲区的稳定测试步骤开始程序的运行运行人工智能操作测试数据苹果生产者 5苹果消费者 5橘子生产者 3橘子消费者 0 减少苹果生产者到0增加苹果消费者数量到6预期结果缓冲区开始被操作生产者、消费者数量都靠拢至4测试结果与预期相符与预期相符与预期相符2、调试分析:(1)程序编写过程中,因为有两个生产者和消费者,极易把操作写错。在编写增加苹果数量额函数中,程序中午无法增加苹果数量。解决办法:在函数中查找错误,对苹果的操作写成了对橘子的操作,导致程序出现问题。(2)在对缓冲区进行绘图的时候,java的JComponent组件内绘图位置出现错误。解决办法:JComponent内绘图时因为JComponent内使用的是相对坐标,所以不能使用面板的绝对坐标,换成相对坐标正确绘图。(3)实现人工智能操作的时候,点击相应按钮无法执行解决办法:在排查完毕后,发现按键响应没有对程序已经设计的标志值进行修改,致使程序没有按预期执行,修改完标志值即可以。五、用户手册1.使用的语言和平台本次实验使用的是java 语言的eclipse平台2.对于程序运行环境的注意事项需要安装java运行环境,eclipss平台不需要安装,只需要下载完成就可以使用。3.程序使用步骤图1:系统登录界面。图2:生产者速度调节 图3:消费者速度调节图4:生产者数量调节 图5:消费者数量调节 图 6::控制界面图7:动态可视化缓冲区4.程序使用步骤:1)单击开始按钮,程序开始初始化执行2)点击增加按钮分别增加生产者和消费者,可以看到可视化缓冲区开始运动3)在速度调节部分调节生产者和消费者的速度,可以看到缓冲区出现预期的产品种类和数量的变化。4)在程序运行状态,可以点击“人工智能”按钮,可以实现人工智能自动操作缓冲区,保持缓冲区的产品数量和种类的稳定,不至于产品数量过多或过少,也不会出现某种产品数量过多或者过少。六、程序清单import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.geom.Ellipse2D;import java.awt.geom.Rectangle2D;import java.awt.*;import java.net.MalformedURLException;import java.util.ArrayList;import javax.print.attribute.AttributeSet;import javax.swing.*;import org.w3c.dom.css.Rect;public class Apple/* * 生成一个缓冲池类对应的对象叫myStorage,以后所有的生产者线程 和消费者线程都对这个myStorage对象进行操作! */ static MyStorage myStorage = new MyStorage();private JFrame window ;/ 该数组用来存取生产橘子和苹果的线程,分别20个static Increaseapple appleincrease = new Increaseapple20;static Increaseorange orangeincrease = new Increaseorange20;/ 该数组用来存放消费者线程,最多20个static Decreaseapple appledecrease = new Decreaseapple20;static Decreaseorange orangedecrease = new Decreaseorange20;/ 代表两个生产者对应线程的数目,i1为苹果,i2为橘子static int i1 = 0;static int i2 = 0;/ 代表消费者对应线程的数目,d1为苹果,d2为橘子static int d1 = 0;static int d2 = 0;static TextArea textArea1;static TextArea textArea2;static JProgressBar progressbar = new JProgressBar(0,20);static Draw draw1; static JTextField t1;static JTextField t2;static JTextField t3;static JTextField t4;public void createMainWindow()window = new JFrame(橘子苹果问题);window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);window.setSize(700,700);window.setResizable(false);JPanel panel = new JPanel();panel.setLayout(null);JLabel App1 = new JLabel(生产苹果者数:);App1.setBounds(10, 500,100,25);panel.add(App1);progressbar.setStringPainted(true);progressbar.setBounds(200,640,300,30);panel.add(progressbar);progress p = new progress(myStorage);p.start();draw1 = new Draw(myStorage);draw1.setBounds(0,0,700,300);panel.add(draw1);t1 = new JTextField();t1.setBounds(120,500,60,25);t1.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(t1);JButton inapp1 = new JButton(增加);inapp1.setBounds(190, 500, 60, 25);panel.add(inapp1);inapp1.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)if (i1 0)decreaseappleProducer();t1.setText(String.valueOf(i1););JLabel Org1 = new JLabel(生产橘子者数:);Org1.setBounds(10, 550,100,25);panel.add(Org1);t2 = new JTextField();t2.setBounds(120,550,60,25);t2.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(t2);JButton inorg1 = new JButton(增加);inorg1.setBounds(190, 550, 60, 25);panel.add(inorg1);inorg1.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)if (i2 0)decreaseorangeProducer();t2.setText(String.valueOf(i2););/*消费者的数目设置 苹果核橘子*/JLabel App2 = new JLabel(消费苹果者数:);App2.setBounds(330,500,100,25);panel.add(App2);t3 = new JTextField();t3.setBounds(440,500, 60, 25);panel.add(t3);JButton inapp2 = new JButton(增加);inapp2.setBounds(510,500, 60, 25);panel.add(inapp2);inapp2.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)if (d1 0)decreaseappleConsumer();t3.setText(String.valueOf(d1););JLabel Org2 = new JLabel(消费橘子者数:);Org2.setBounds(330,550,100,25);panel.add(Org2);t4 = new JTextField();t4.setBounds(440,550, 60, 25);panel.add(t4);JButton inorg2 = new JButton(增加);inorg2.setBounds(510,550, 60, 25);panel.add(inorg2);inorg2.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)if (d2 0)decreaseorangeConsumer();t4.setText(String.valueOf(d2););/* * 这里的代码是实现了设计要求中的第三条:生产者速度可调。 */JLabel appsp1 = new JLabel(苹果生产速度:);appsp1.setBounds(10,400,100,25);panel.add(appsp1);final JTextField tsp1 = new JTextField();tsp1.setBounds(120, 400, 60, 25);tsp1.setText(String.valueOf(Increaseapple.speed);tsp1.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(tsp1);JButton appalter1 = new JButton(修改);appalter1.setBounds(190, 400, 60, 25);panel.add(appalter1);/ 在这里实现了控制生产速度的功能appalter1.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)String str1 = tsp1.getText();long i = Long.parseLong(str1);if (i = 0)Increaseapple.speed = i;else if (i 0)Increaseapple.speed = 0;tsp1.setText(String.valueOf(Increaseapple.speed);elseIncreaseapple.speed = 10000;tsp1.setText(String.valueOf(Increaseapple.speed););/* * 这里的代码是实现了设计要求中的第三条:生产者速度可调。 */JLabel orgsp1 = new JLabel(橘子生产速度:);orgsp1.setBounds(10,450,100,25);panel.add(orgsp1);final JTextField tsp2 = new JTextField();tsp2.setBounds(120, 450, 60, 25);tsp2.setText(String.valueOf(Increaseapple.speed);tsp2.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(tsp2);JButton orgalter1 = new JButton(修改);orgalter1.setBounds(190, 450, 60, 25);panel.add(orgalter1);/ 在这里实现了控制生产速度的功能orgalter1.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)String str1 = tsp2.getText();long i = Long.parseLong(str1);if (i = 0)Increaseapple.speed = i;else if (i 0)Increaseapple.speed = 0;tsp2.setText(String.valueOf(Increaseorange.speed);elseIncreaseapple.speed = 10000;tsp2.setText(String.valueOf(Increaseorange.speed););/* * 这里的代码是实现了设计要求中的第三条:消费者速度可调。 */JLabel appsp2 = new JLabel(苹果消费速度);appsp2.setBounds(260,400, 100, 25);panel.add(appsp2);final JTextField tsp3 = new JTextField();tsp3.setBounds(370,400, 60, 25);tsp3.setText(String.valueOf(Decreaseapple.speed);tsp3.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(tsp3);JButton appalter2 = new JButton(修改);appalter2.setBounds(440,400, 60, 25);panel.add(appalter2);/ 这里实现了控制消费速度的功能appalter2.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)String str2 = tsp3.getText();long i = Long.parseLong(str2);if (i = 0)Decreaseapple.speed = i;else if (i 0)Decreaseapple.speed = 0;tsp3.setText(String.valueOf(Decreaseapple.speed);elseDecreaseapple.speed = 10000;tsp3.setText(String.valueOf(Decreaseapple.speed););JLabel orgsp2 = new JLabel(橘子消费速度);orgsp2.setBounds(260,450,100, 25);panel.add(orgsp2);final JTextField tsp4 = new JTextField();tsp4.setBounds(370,450, 60, 25);tsp4.setText(String.valueOf(Decreaseapple.speed);tsp4.addKeyListener(new KeyAdapter()public void keyTyped(KeyEvent event)char ch = event.getKeyChar();if (ch 9)event.consume(););panel.add(tsp4);JButton orgalter2 = new JButton(修改);orgalter2.setBounds(440,450, 60, 25);panel.add(orgalter2);orgalter2.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)String str2 = tsp4.getText();long i = Long.parseLong(str2);if (i = 0)Decreaseorange.speed = i;else if (i 0)Decreaseorange.speed = 0;tsp4.setText(String.valueOf(Decreaseorange.speed);elseDecreaseorange.speed = 10000;tsp4.setText(String.valueOf(Decreaseorange.speed););/* * 这里构造了能够实现第五条要求的组件,可以显示当前线程的状态,实现了设计要求中的第五条。 */textArea2 = new TextArea();textArea2.setBounds(0,300 ,350,100);panel.add(textArea2);textArea1 = new TextArea();textArea1.setBounds(350,300,350,100);panel.add(textArea1);/* * 这里的代码实现了设计要求第六条,定义了开始,暂停,停止三个按钮,按开始按钮线程将开始执行 生产和消费。 * 可以在运行时按暂停按钮来暂停线程的生产和消费,以便查看當前線程的狀態。按停止,则所有的线程都将被强制中止执行。 */JButton start = new JButton(开始);start.setBounds(50, 600, 60, 25);panel.add(start);/ 开始按钮start.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)Increaseapple.applepause1 = 1;Decreaseapple.applepause2 = 1;Increaseorange.orangepause1 = 1;Decreaseorange.orangepause2 = 1;DrawRect rect = new DrawRect(myStorage);rect.start();t1.setText(String.valueOf(i1);t2.setText(String.valueOf(i2);t3.setText(String.valueOf(d1);t4.setText(String.valueOf(d2););JButton sus = new JButton(暂停);sus.setBounds(200,600,60,25);panel.add(sus);sus.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)textArea2.append(-n);Increaseapple.applepause1 = 0;Decreaseapple.applepause2 = 0;Increaseorange.orangepause1 = 0;Decreaseorange.orangepause2 = 0;);JButton halt = new JButton(停止);halt.setBounds(350,600, 60, 25);panel.add(halt);halt.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)for (int a = 0; a i1; a+)appleincreasea.out = true;appleincreasea = null;for (int a = 0; a i2; a+)orangeincreasea.out = true;orangeincreasea = null;for (int a = 0; a d1; a+)appledecreasea.out = true;appledecreasea = null;for (int a = 0; a d2; a+)orangedecreasea.out = true;orangedecreasea = null;i1 = 0;i2 = 0;d1 = 0;d2 = 0;t1.setText(String.valueOf(i1);t2.setText(String.valueOf(i2);t3.setText(String.valueOf(d1);t4.setText(String.valueOf(d2););JButton Ai = new JButton(人工智能);Ai.setBounds(420,600, 100, 25);Ai.addActionListener(new ActionListener()Overridepublic void actionPerformed(ActionEvent e)Decreaseorange.AI = 1;Decreaseapple.AI = 1;Increaseapple.AI = 1;Increaseorange.AI = 1;);panel.add(Ai);window.add(panel); window.setVisible(true);/* * 下面这两个方法分别是往增加、开始和减少、终止生产者线程的方法。 将线程存入生产者线程数组或从数组中移除。 * 每当调用一次该方法,就增加或减少一个生产者线程。 * * return */public static int increaseappleProducer()if(i1 20)appleincreasei1 = new Increaseapple(myStorage);appleincreasei1.start();i1+;return i1;public static int increaseorangeProducer()if(i2 0)appleincreasei1 - 1.out = true;appleincreasei1 - 1 = null;i1-;return i1;public static int decreaseorangeProducer()if(i2 0)orangeincreasei2 - 1.out = true;orangeincreasei2 - 1 = null;i2-;return i2;public static int increaseappleConsumer()if(d1 20)appledecreased1 = new Decreaseapple(myStorage);appledecreased1.start();d1+;return d1;public static int increaseorangeConsumer()if(d2 0)appledecreased1 - 1.out = true;appledecreased1 - 1 = null;d1-;return d1;public static int decreaseorangeConsumer()if(d2 0)orangedecreased2 - 1.out = true;orangedecreased2 - 1 = null;d2-;return d2;/* * main方法,程序从这里执行,执行后显示主界面。所有功能在主界面中 调节。 * * param args */public static void main(String args)Apple mainWindow = new Apple();mainWindow.createMainWindow();class Draw extends JComponentprivate MyStorage mystorage ;public Draw(MyStorage mystorage)this.mystorage = mystorage;public void paint(Graphics g)for(int i = 0 ;i 20; i+)g.setColor(Color.BLACK);g.drawRect(30*i+50, 130,30,40);if(mystorage.pooli = 1)g.setColor(Color.RED);g.fillRect(30*i+51,131,29,39);else if(mystorage.
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!