【C# winform】操作系统:进程同步程序设计

您所在的位置:网站首页 多进程程序设计 【C# winform】操作系统:进程同步程序设计

【C# winform】操作系统:进程同步程序设计

2024-06-21 21:35| 来源: 网络整理| 查看: 265

实验内容

桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,儿子专门等待吃盘子中的橘子,女儿专门等吃盘子中的苹果。试编程实现爸爸、妈妈、儿子、女儿四个人之间的同步。 (1)水果、盘子均通过导入图片来实现可视化; (2)放水果、拿水果均有动画显示,包括把水果拿到手上去放、放完空手回来等均通过的动画予以展示; (3)执行顺序由并发控制机制决定,而非通过延时实现; (4)要求界面美观、动作流畅。

实验过程

实验伪代码:

main() { int mutex=1; //实现父母子女对盘子的互斥访问 int empty=2; //盘子目前能存放的水果数 int apple=0; //盘子里的苹果数 int orange=0; //盘子里的橘子数 cobegin father(); mother(); son(); daughter(); coend } void father() { p(empty); p(mutex); 往盘子里放苹果; v(mutex); v(apple); } void mother() { p(empty); p(mutex); 往盘子里放橘子; v(mutex); v(orange); } void son() { p(orange); p(mutex); 从盘子里取橘子; v(mutex); v(empty); } void daughter() { p(apple); p(mutex); 从盘子里取苹果; v(mutex); v(empty); }

C# winform实现代码:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp3 { public partial class Form1 : Form { //启动标志 public static bool start_flag = false; //互斥信号量,实现对盘子的互斥访问 public static Mutex mutex = new Mutex(); //同步信号量 public static Semaphore full, apple, orange; //苹果、橘子和盘子中水果的数量 public static int apple_num = 0; public static int orange_num = 0; public static int is_full = 0; public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { apple_1.Visible = false; apple_2.Visible = false; orange_1.Visible = false; orange_2.Visible = false; full = new Semaphore(2, 2); apple = new Semaphore(0, 2); orange = new Semaphore(0, 2); for (int i = 0; i mutex.WaitOne(); //申请访问盘子资源 //盘子装满 if (is_full == 2) { F_hand_move(); mutex.ReleaseMutex(); //释放对盘子资源的访问 System.Threading.Thread.Sleep(500); } //盘子未满 else { full.WaitOne(); //申请一个盘子空位 apple_num += 1; //苹果的数量加1 F_hand_move(); //父亲往盘中放苹果 is_full += 1; //盘子水果数量加1 apple.Release(); //苹果资源数加1 mutex.ReleaseMutex(); //释放对盘子资源的访问 } } public void Mother() { mutex.WaitOne(); if (is_full == 2) { M_hand_move(); mutex.ReleaseMutex(); System.Threading.Thread.Sleep(500); } else { full.WaitOne(); M_hand_move(); orange_num += 1; is_full += 1; orange.Release(); mutex.ReleaseMutex(); } } public void Son() { mutex.WaitOne(); //申请对盘子资源的访问 //盘中无苹果 if (apple_num == 0) { S_hand_move(); mutex.ReleaseMutex(); //释放对盘子资源的访问 System.Threading.Thread.Sleep(500); } //盘中有苹果 else { apple.WaitOne(); S_hand_move(); apple_num -= 1; //苹果数量减1 is_full -= 1; //盘中水果数量减1 full.Release(); //盘中水果资源数减1 mutex.ReleaseMutex(); //释放对盘子资源的访问 } } public void Daughter() { mutex.WaitOne(); if (orange_num == 0) { D_hand_move(); mutex.ReleaseMutex(); System.Threading.Thread.Sleep(500); } else { orange.WaitOne(); D_hand_move(); orange_num -= 1; is_full -= 1; full.Release(); mutex.ReleaseMutex(); } } //爸爸的手的动画 public void F_hand_move() { int x = 180,y = 120; //爸爸的手的初始位置为(180,120) int n = 10; if (apple_1.Visible == false && orange_1.Visible == false) //盘子左边无水果 { for (int i = 0; i x -= 15; y -= 8; father_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (apple_2.Visible == false && orange_2.Visible == false)//盘子右边无水果 { for (int i = 0; i x -= 21; y -= 8; father_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (is_full == 2) //两边均有水果 { for (int i = 0; i x -= 12; y -= 8; father_hand.Location = new Point(x, y); Thread.Sleep(100); } } } //妈妈的手的动画 public void M_hand_move() { int x = 540, y = 120; //妈妈的手的初始位置(540,120) int n = 10; if (apple_1.Visible == false && orange_1.Visible == false) { for (int i = 0; i x += 21; y -= 8; mother_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (apple_2.Visible == false && orange_2.Visible == false) { for (int i = 0; i x += 15; y -= 8; mother_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (is_full == 2) { for (int i = 0; i x += 12; y -= 8; mother_hand.Location = new Point(x, y); Thread.Sleep(100); } } } //儿子的手的动画 public void S_hand_move() { int x = 180,y = 280; //儿子的手的初始位置(180,280) int n = 10; if (apple_1.Visible == true) //盘子左边有苹果 { for (int i = 0; i x -= 15; y += 8; son_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (apple_2.Visible == true) //盘子右边有苹果 { for (int i = 0; i x -= 21; y += 8; son_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (apple_num == 0) //盘中无苹果 { for (int i = 0; i x -= 12; y += 8; son_hand.Location = new Point(x, y); Thread.Sleep(100); } } } //女儿的手的动画 public void D_hand_move() { int x = 540,y = 280; //女儿的手的初始位置为(540,280) int n = 10; daughter_hand.Location = new Point(x, y); if (orange_1.Visible == true) { for (int i = 0; i x += 21; y += 8; daughter_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (orange_2.Visible == true) { for (int i = 0; i x += 15; y += 8; daughter_hand.Location = new Point(x, y); Thread.Sleep(100); } } else if (orange_num == 0) { for (int i = 0; i x += 12; y += 8; daughter_hand.Location = new Point(x, y); Thread.Sleep(100); } } } private void Stop_Click(object sender, EventArgs e) { Environment.Exit(0); } } } 实验结果 实验心得

通过本次苹果橘子的“多生产者-多消费者”实验,加深了我对进程和程序的区别的理解:进程是程序的依次执行过程,程序是一个指令序列。此外,我对互斥信号量和同步信号量的使用更加熟练:当存在临界资源时,需要设置互斥信号量;在不同的操作存在先后顺序时,需要设置同步信号量。最后,就本问题而言,在考虑进程的操作流程时,可以从“事件”的角度来考虑,而非从单个进程行为的角度考虑。因此,不必考虑女儿或儿子从盘中取出水果产生空位才可取出水果,可以认为当盘中存在空位时,即可放入水果。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3