欢迎光临
我们一直在努力

哲学家就餐问题的C#实现-.NET教程,C#语言

建站超值云服务器,限时71元/月

撰文:周翔

这是我在上操作系统课的那个学期写的一段程序,并组织成了一篇文章。当初被我的挚友曾毅发表在cstc的论坛上:http://cstc.net.cn/bbs/viewtopic.php?t=457,在此,我把它贴在这儿,希望对大家有所裨益。

学操作系统的进程同步都要涉及到三个经典问题:生产者-消费者问题、读者-写者问题和哲学家就餐问题。下面来介绍一下哲学家就餐问题:

哲学家就餐问题中,一组哲学家围坐在一个圆桌旁,每个哲学家的左边都只有一只筷子(当然他的右边也有一只筷子,但是这是他右边哲学家的左边的筷子),他们吃完了就思考,思考了一会就会饿,饿了就想吃,然而,为了吃饭,他们必须获得左边和右边的筷子。当每个哲学家只拿有一只筷子的时候,会坐者等另一只筷子,在每个哲学家都只拿一个筷子的时候,就会发生死锁。传统的解决死锁问题的方法是引用管程的概念,但是在c#中来实现的话可以使system.threading中的mutex为每个哲学家来声名两个信号量rightchopstick和leftchopstick,在主程序中用5个mutex赋值给它,用waithandle来实现对筷子的独占访问。这个例子是用windows图形界面实现,用事件来通知界面哲学家的状态。

以下是代码(在vs.net 下运行通过):

//diningphilosophers.cs———-code:seafrog—————————————————–

using system;

using system.threading;

using system.windows.forms;

using seafrog.threading;

using seafrog.philosopher;

namespace diningphilosophers

{

public class form1 : system.windows.forms.form

{

private system.windows.forms.button button1;

private system.componentmodel.container components = null;

private system.windows.forms.listbox listbox1;

private philosopher[] p=new philosopher[5];

public form1()

{

initializecomponent();

mutex[] chopsticks=new mutex[5];

for(int i=0;i<5;i++)

{

chopsticks[i]=new mutex(false);

}

for(int i=0;i<5;i++)

{

philosopherdata pd;

pd.philosopherid=i;

pd.rightchopstick=chopsticks[(i+1)%5];

pd.leftchopstick=chopsticks[(i+4)%5];

pd.amounttoeat=5;

pd.totalfood=35;

p[i]=new philosopher(pd);

p[i].messagearrival+=new philosopher.messagearrivedhandler(showmessage);

}

}

protected override void dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.dispose();

}

}

base.dispose( disposing );

}

#region windows form designer generated code

private void initializecomponent()

{

this.button1 = new system.windows.forms.button();

this.listbox1 = new system.windows.forms.listbox();

this.suspendlayout();

//

// button1

//

this.button1.location = new system.drawing.point(8, 224);

this.button1.name = "button1";

this.button1.size = new system.drawing.size(272, 40);

this.button1.tabindex = 1;

this.button1.text = "go to restaurant";

this.button1.click += new system.eventhandler(this.button1_click);

//

// listbox1

//

this.listbox1.itemheight = 12;

this.listbox1.name = "listbox1";

this.listbox1.size = new system.drawing.size(296, 220);

this.listbox1.tabindex = 2;

//

// form1

//

this.autoscalebasesize = new system.drawing.size(6, 14);

this.clientsize = new system.drawing.size(292, 273);

this.controls.addrange(new system.windows.forms.control[] {

this.listbox1,

this.button1});

this.name = "form1";

this.text = "form1";

this.resumelayout(false);

}

#endregion

[stathread]

static void main()

{

application.run(new form1());

}

private void button1_click(object sender, system.eventargs e)

{

for(int i=0;i<5;i++)

p[i].start();

}

public void showmessage(object sender,messagearrivedeventargs e)

{

switch(e.type)

{

case philosopher.ready:

listbox1.items.add("philosopher("+e.philosopherdata.philosopherid+") ready.");

break;

case philosopher.eating:

listbox1.items.add("philosopher("+

e.philosopherdata.philosopherid+") eating "+

e.philosopherdata.amounttoeat+" of "+

e.philosopherdata.totalfood+" food.");

break;

case philosopher.thinking:

listbox1.items.add("philosopher("+e.philosopherdata.philosopherid+") thinking.");

break;

case philosopher.finished:

listbox1.items.add("philosopher("+e.philosopherdata.philosopherid+") finished.");

break;

}

}

}

}

//basethread.cs———-code:seafrog——————————————————–

using system;

using system.threading;

namespace seafrog.threading

{

//工作线程抽象类,作为对线程操作的封装。

public abstract class workerthread

{

private object threaddata;

private thread thisthread;

public object data

{

get{return threaddata;}

set{threaddata=value;}

}

public object isalive

{

get{return thisthread==null?false:thisthread.isalive;}

}

public workerthread(object data)

{

this.threaddata=data;

}

public workerthread()

{

threaddata=null;

}

public void start()

{

thisthread=new thread(new threadstart(this.run));

thisthread.start();

}

public void stop()

{

thisthread.abort();

while(thisthread.isalive);

thisthread=null;

}

protected abstract void run();

}

}

//philosophers.cs———-code:seafrog——————————————————–

using system;

using system.threading;

using seafrog.threading;

namespace seafrog.philosopher

{

//封装哲学家数据的结构

public struct philosopherdata

{

public int philosopherid;

public mutex rightchopstick;

public mutex leftchopstick;

public int amounttoeat;

public int totalfood;

}

public class philosopher : seafrog.threading.workerthread

{

public const int ready=0;

public const int eating=1;

public const int thinking=2;

public const int finished=3;

public philosopher(object data):base(data){}

public delegate void messagearrivedhandler(object sender,messagearrivedeventargs args);

public event messagearrivedhandler messagearrival;

public static int finished=0;

protected override void run()

{

philosopherdata pd=(philosopherdata)data;

random r=new random(pd.philosopherid);

messagearrival(this,new messagearrivedeventargs(ready,pd));

waithandle[] chopsticks=new waithandle[]{pd.leftchopstick,pd.rightchopstick};

while(pd.totalfood>0)

{

//如果两边的哲学家拿着筷子,则等待。

waithandle.waitall(chopsticks);

//否则,吃饭。

messagearrival(this,new messagearrivedeventargs(eating,pd));

//把饭吃掉一部分。

pd.totalfood-=pd.amounttoeat;

thread.sleep(r.next(1000,5000));

messagearrival(this,new messagearrivedeventargs(thinking,pd));

//放下左边和右边的筷子。

pd.rightchopstick.releasemutex();

pd.leftchopstick.releasemutex();

thread.sleep(r.next(1000,5000));

}

//饭都吃完了。

messagearrival(this,new messagearrivedeventargs(finished,pd));

if(++finished==4)

system.windows.forms.messagebox.show("all finished!");

}

}

//事件:用来通知主窗体现在哲学家的状态。

public class messagearrivedeventargs : eventargs

{

public int type;

public philosopherdata philosopherdata;

public messagearrivedeventargs(int t,philosopherdata pd)

{

type=t;

philosopherdata=pd;

}

}

}

( 完)

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 哲学家就餐问题的C#实现-.NET教程,C#语言
分享到: 更多 (0)

相关推荐

  • 暂无文章