操作系统实验——进程同步 C#实现

一、实习内容

模拟实现同步机构,以避免发生进程执行时可能出现的与时间有关的错误。

二、实习目的

当进程并发执行时,如果对进程访问的共享变量不加限制,就会产生“与时间有关”的错误。为了防止这类错误,系统必须用同步机构来控制进程对共享变量的访问。
一般说,同步机构是由若干条同步原语所组成。本实验要求学生模拟P、V操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

三、实习题目

模拟P、V操作实现同步机构,且用P、V操作解决生产者—消费者问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;



//每运行一条指令都要敲一下回车
namespace CaoZuoXiTong5
{
    class Program
    {

        static int[] area = new int[10];
        static int empty = 10;
        static int full = 0;

        static int direction = 0;//0表示都可以,1表示只能运行producer,2表示只能运行consumer
        static void Main(string[] args)
        {
            int a;
            Console.WriteLine("随机运行Producer Consumer");
            Producer producer = new Producer();
            Consumer consumer = new Consumer();

            while (true)
            {
                Random x = new Random();
                a = x.Next(1, 3);


                if (direction == 1) 
                {
                    a = 1;
                }
                else if (direction == 2)
                {
                    a = 2;
                }

                switch (a)
                {
                    case 1:producer.Choose();break;
                    case 2:consumer.Choose();break;
                    default:break;
                }

                Console.WriteLine("---------------------\n缓冲区:{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}",area[0], area[1], area[2], area[3], area[4], area[5], area[6], area[7], area[8], area[9]);
                Console.WriteLine("Producer:{0} Consumer:{1}",producer.Statement,consumer.Statement);
                Console.WriteLine("Producer断点:{0} Consumer断点:{1}",producer.Point,consumer.Point);

                Console.ReadLine();
            }

        }

        
        static int P( ref int x) 
        {
            int a = x;
            a--;          
            if (a< 0) return 0;//不能运行,需要等待
            else
            {
                x--;
                return 1;//可以运行
            }
        }

        static void V(ref int x)
        {
            x++;

        }

        class Consumer
        {
            public int Point { get; set; }
            public string Statement { get; set; }
            public Consumer()
            {
                Point = 0;
                Statement = "运行";
            }

            public void Choose()
            {
                switch (this.Point)
                {
                    case 0:A(); break;
                    case 1: B(); break;
                    case 2: C(); break;
                    case 3: D();break;
                    case 4: E(); break;
                    case 5: A(); break;
                    default: A(); B(); C(); D(); E(); break;
                }
            }

            public void A()
            {
                int judge = P(ref full);
                Console.WriteLine("Consumer:产品P操作");
                if (judge == 0)
                {
                    Console.WriteLine("Consumer:Consumer因P操作进程阻塞");
                    this.Point = 0;
                    this.Statement = "等待";
                    direction = 1;
                }
                else
                {
                    this.Point = 1;
                    this.Statement = "运行";
                }
            }
            public void B()
            {
                Console.WriteLine("Consumer:取出一个产品");
                for (int i = 0; i < 10; i++)
                {
                    if (area[i] == 1)
                    {
                        area[i] = 0;
                        break;
                    }
                }
                this.Point = 2;
            }
            public void C()
            {
                V(ref empty); 
                direction=0;
                Console.WriteLine("Consumer:缓冲区V操作");
                this.Point = 3;
            }

            public void D()
            {
                Console.WriteLine("Consumer:消耗一个产品:1");
                this.Point = 4;
            }

            public void E()
            {
                Console.WriteLine("Consumer:GOTO");
                this.Point = 5;
            }
        }
        class Producer
        {
            public int Point { get; set; }
            public string Statement { get; set; }

            public Producer()
            {
                Point = 0;
                Statement = "运行";
            }

            public void Choose()
            {
                switch (this.Point)
                {
                    case 0: A(); break;
                    case 1: B(); break;
                    case 2: C(); break;
                    case 3: D(); break;
                    case 4: E(); break;
                    case 5: A();break;
                    default: A(); B(); C(); D(); E(); break;
                }
            }

            public void A()
            {
                Console.WriteLine("Producer:生产了一个产品:1");
                this.Point = 1;
            }
            public void B()
            {
                int judge = P(ref empty);
                Console.WriteLine("Producer:缓冲区P操作");

                if (judge == 0)
                {
                    Console.WriteLine("Producer:Producer因P操作进程阻塞");
                    direction = 2;
                    this.Point = 1;
                    this.Statement = "等待";
                }
                else this.Point = 2;
                this.Statement = "运行";
            }
            public void C()
            {
                for (int i = 0; i < 10; i++)
                {
                    if (area[i] == 0)
                    {
                        area[i] = 1;
                        break;
                    }
                }
                Console.WriteLine("Producer:放入一个产品");
                this.Point = 3;
            }

            public void D()
            {
                V(ref full);
                direction=0;
                Console.WriteLine("Producer:产品V操作");
                this.Point = 4;
            }

            public void E()
            {
                Console.WriteLine("Producer:GOTO");
                this.Point = 5;
            }
        }
    }

    
}

才疏学浅,如有错误请多指正

转载请注明出处

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模拟进程管理 #include <stdio.h> #include <malloc.h> //Can only be used in independent situation; //#define getmem(type) (type*)malloc(sizeof(type)) #define buffersize 5 int processnum=0;//the num of processes struct pcb { /* 定义进程控制块PCB */ int flag;//flag=1 denote producer;flag=2 denote consumer; int numlabel; char product; char state; struct pcb* processlink; }*exe=NULL,*over=NULL; typedef struct pcb PCB; PCB* readyhead=NULL,* readytail=NULL; PCB* consumerhead=NULL,* consumertail=NULL; PCB* producerhead=NULL,* producertail=NULL; //产品数量 int productnum=0; int full=0,empty=buffersize;// semaphore char buffer[buffersize];//缓冲区 int bufferpoint=0;//缓冲区指针 void linkqueue(PCB* process,PCB** tail); PCB* getq(PCB* head,PCB** tail); bool hasElement(PCB* pro); void display(PCB* p); void linklist(PCB* p,PCB* listhead); void freelink(PCB* linkhead); bool processproc(); bool waitempty(); bool waitfull(); void signalempty(); void signalfull(); void producerrun(); void comsuerrun(); bool hasElement(PCB* pro); void linklist(PCB* p,PCB* listhead) { PCB* cursor=listhead; while(cursor->processlink!=NULL){ cursor=cursor->processlink; } cursor->processlink=p; } void freelink(PCB* linkhead) { PCB* p; while(linkhead!=NULL){ p=linkhead; linkhead=linkhead->processlink; free(p); } } void linkqueue(PCB* process,PCB** tail) { if((*tail)!=NULL){ (*tail)->processlink=process; (*tail)=process; } else{ printf("队列未初始化!"); } } PCB* getq(PCB* head,PCB** tail) { PCB* p; p=head->processlink; if(p!=NULL){ head->processlink=p->processlink; p->processlink=NULL; if( head->processlink ==NULL ) (*tail)=head; } else return NULL; return p; } bool processproc() { int i,f,num; char ch; PCB* p=NULL; PCB** p1=NULL; printf("\n 请输入希望产生的进程个数?"); scanf("%d",&num); getchar(); // if(num>=100){ // printf("您怎么要产生这么多进程!Demands Denied!"); // return false; // } for(i=0;i<num;i++){ printf("\n 请输入您要产生的进程:输入1为生产者进程;输入2为消费者进程\n"); scanf("%d",&f); getchar(); p=(PCB*)malloc(sizeof(PCB)) ; if( !p) { printf("内存分配失败"); return false; } p->flag=f; processnum++; p->numlabel=processnum; p->state='w'; p->processlink=NULL; if(p->flag==1){ printf("您要产生的进程是生产者,它是第%d个进程。请您输入您要该进程产生的字符!\n",processnum); scanf("%c",&ch); getchar(); p->product=ch; productnum++; printf("您要该进程产生的字符是%c \n",p->product); } else { printf("您要产生的进程是消费者,它是第%d个进程。\n",p->numlabel); } linkqueue(p,&readytail); } return true; } bool waitempty() { if(empty<=0) { printf("进程%d:缓冲区存数,缓冲区满,该进程进入生产者等待队列\n",exe->numlabel); linkqueue(exe,&producertail); return false; } else{ empty--; return true; } } void signalempty() { PCB* p; if(hasElement(producerhead)){ p=getq(producerhead,&producertail); linkqueue(p,&readytail); printf("等待中的生产者进程进入就绪队列,它的进程号是%d\n",p->numlabel); } empty++; } bool waitfull() { if(full<=0) { printf("进程%d:缓冲区取数,缓冲区空,该进程进入消费者等待队列\n",exe->numlabel); linkqueue(exe,&consumertail); return false; } else{ full--; return true;} } void signalfull() { PCB* p; if(hasElement(consumerhead)){ p=getq(consumerhead,&consumertail); linkqueue(p,&readytail); printf("等待中的消费者进程进入就绪队列,它的进程号是%d\n",p->numlabel); } full++; } void producerrun() { if(!waitempty()) return; printf("进程%d开始向缓冲区存数%c\n",exe->numlabel,exe->product); buffer[bufferpoint]=exe->product; bufferpoint++; printf("进程%d向缓冲区存数操作结束\n",exe->numlabel); signalfull(); linklist(exe,over); } void comsuerrun() { if(!waitfull()) return; printf("进程%d开始向缓冲区取数\n",exe->numlabel); exe->product=buffer[bufferpoint-1]; bufferpoint--; printf("进程%d向缓冲区取数操作结束,取数是%c\n",exe->numlabel,exe->product); signalempty(); linklist(exe,over); } void display(PCB* p) { p=p->processlink; while(p!=NULL){ printf("进程%d,它是一个",p->numlabel); p->flag==1? printf("生产者\n"):printf("消费者\n"); p=p->processlink; } } bool hasElement(PCB* pro) { if(pro->processlink==NULL) return false; else return true; } void main() { char terminate; bool element; printf("你想开始程序吗?(y/n)"); scanf("%c",&terminate); getchar(); //Queue initialize; readyhead=(PCB*)malloc(sizeof(PCB)); if(readyhead==NULL) return; readytail=readyhead; readyhead->flag=3; readyhead->numlabel=processnum; readyhead->state='w'; readyhead->processlink=NULL; consumerhead=(PCB*)malloc(sizeof(PCB)); if(consumerhead==NULL) return; consumertail=consumerhead; consumerhead->processlink=NULL; consumerhead->flag=4; consumerhead->numlabel=processnum; consumerhead->state='w'; consumerhead->processlink=NULL; producerhead=(PCB*)malloc(sizeof(PCB)); if(producerhead==NULL) return; producertail=producerhead; producerhead->processlink=NULL; producerhead->flag=5; producerhead->numlabel=processnum; producerhead->state='w'; producerhead->processlink=NULL; over=(PCB*)malloc(sizeof(PCB)); if(over==NULL) return; over->processlink=NULL; while(terminate=='y') { if(!processproc()) break; element=hasElement(readyhead); while(element){ exe=getq(readyhead,&readytail); printf("进程%d申请运行,它是一个",exe->numlabel); exe->flag==1? printf("生产者\n"):printf("消费者\n"); if(exe->flag==1) producerrun(); else comsuerrun(); element=hasElement(readyhead); } printf("就绪队列没有进程\n"); if(hasElement(consumerhead)) { printf("消费者等待队列中有进程:\n"); display(consumerhead); } else { printf("消费者等待队列中没有进程\n"); } if(hasElement(producerhead)) { printf("生产者等待队列中有进程:\n"); display(producerhead); } else { printf("生产者等待队列中没有进程\n"); } printf("你想继续吗?(press 'y' for on)"); scanf("%c",&terminate); getchar(); } printf("\n\n 进程模拟完成.\n"); //Free the room; freelink(over); over=NULL; freelink(readyhead); readyhead=NULL; readytail=NULL; freelink(consumerhead); consumerhead=NULL; consumertail=NULL; freelink(producerhead); producerhead=NULL; producertail=NULL; getchar(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值