ผู้สนับสนุน

วันอาทิตย์ที่ ๑๓ เมษายน พ.ศ. ๒๕๕๑

'''
Dinning Philosopher Symmetric
Moss Rookie
ไม่ควรใช้โปรแกรมนี้ในการอ้างอิงในทางวิชาการใดๆ ทั้งสิ้น
เป็นโปรแกรมที่เขียนขึ้นมาเอง ไม่มีการทำความสะอาด source code ทั้งสิ้น

ทำเพื่อเป็นตัวอย่างในการเขียน Thread ใน python แบบง่ายๆ rookie ๆ
และเำพื่อให้เข้าใจปัญหา
Dinning Philosopher ในวิชา OS(ที่เขียนมานี้เป็นในแบบที่ผมเข้าใจ)

โปรแกรมนี้ทำงานโดยจะมีการสร้าง Tread ขึ้นมาตามจำนวนของ
Philosopher
และมีจำนวนของ chopstick เท่ากับจำนวนของ
Philosopher
chopstick เป็นตัวแปลกลางที่ทุก Tread สามารถเข้าถึงได้
โดยมีกฏว่า
1 เมื่อ
Philosopher มี chopstick 2 อันเท่านั้นถึงจะมีโอกาสได้กินอาหาร
2 Philosopher จะสามารถหยิบ
chopstick ได้แค่ที่วางอยู่ข้างตัวเองเท่านั้น
3 มีโอกาสกินอาหารได้แค่ 1 ครั้งเท่านั้นต่อการได้ chopstick ครบคู่(ห้ามถือครอง)
4 ไม่มีใครมีสิทธิ์มากกว่ากัน คือห้ามหยิบ chopstick ที่คนอื่นถือครองอยู่
5 ทุกคนต้องมีโอกาสได้กินอาหาร หรือไม่มีใครรอไปตลอดกาล

การทำงานของโปรแกรม
1 รันด้วย python dinning.py
2 เลือกจำนวนของ
Philosopher
3 ดูผลการทำงาน
4 กด Ctrl+C เพื่อให้ร้านปิดแล้วให้ Philosopher รีบกินให้เสร็จ(ให้ Tread แต่ล่ะตัวจบการทำงาน ก่อนออกจาก program)
'''
import thread
import threading
import random
import time
import signal
#Magic number
#PRINT = 1 Mean print all action
#ON_THE_TABLE = 0 Mean chopsticks is on the table
#Function handler

def handler(signum,frame):

global restaurantOpen
print "Restuarant close"
restaurantOpen = False
def setOutput():
act = 0
while act<1 or act> 2:
try:
act = int(raw_input("All action(1),Eating Only(2)"))
except ValueError:
print "Input must be integer."
if act<1 or act> 2:
print "Enter value 1 xor 2"
return act
def setNumberOfThread():
buf = 11
while buf < 2 or buf> 10:
try:
buf = int(raw_input("How many number of chopstick?"))
except ValueError:
print "Input must be integer."
if buf > 10:
print "Is it to much?"
elif buf < 2:
print "Why? Don't hungry."
return buf
class Philosopher(threading.Thread):
def __init__(self,tno):
threading.Thread.__init__(self)
self.kount = 0
self.tno = tno
# Function to Check "Is dead-lock occur?"
def isdeadlock(self,lis):
flag = True
for i in range(len(lis)):
if lis[i] == ON_THE_TABLE:
return False
if lis[i] == lis[(i+1)%numberOfThread]:
flag = False
return flag
# Philosopher use this function when he hungry
def hungry(self):
# get chopstick to change value
global chopstick
# race: "Who got first chopstick
time.sleep(random.randint(1,5))
# wait forever if can not get 2 chopstick or when deadlock occur
while 1:
#Pick left
if chopstick[self.tno%numberOfThread]==ON_THE_TABLE:
# Show what is it work
if action == PRINT:
print self.tno,"Pick left"
chopstick[self.tno%numberOfThread]=self.tno
# Get left chopstick may cause dead-lock
if self.isdeadlock(chopstick):
print chopstick
if action == PRINT:
print self.tno,"Drop left"
# Than put it down
chopstick[self.tno%numberOfThread]=ON_THE_TABLE
# wait for next time
time.sleep(random.randint(1,5))
# if it has left chopstick now try to pick right chopstick
while chopstick[self.tno%numberOfThread]==self.tno and
chopstick[(self.tno+1)%numberOfThread]==ON_THE_TABLE:
# Note. pick right chopstick does not cause dead-lock because it's right turn
if action == PRINT:
print self.tno,"Pick right"
chopstick[(self.tno+1)%numberOfThread]=self.tno
time.sleep(random.randint(1,3))
# Ready to eat anything
if chopstick[self.tno%numberOfThread]==self.tno and chopstick[(self.tno+1)%numberOfThread]==self.tno:break
def eating(self):
print self.tno,"Eating"
if action == PRINT:
print chopstick
time.sleep(random.randint(1,2))
def think(self):
if action == PRINT:
print self.tno,"Thinking"
time.sleep(random.randint(1,2))
def drop(self):
global chopstick
if action == PRINT:
print self.tno,"Drop right"
chopstick[(self.tno+1)%numberOfThread]=ON_THE_TABLE
time.sleep(random.randint(1,2))
if action == PRINT:
print self.tno,"Drop left"
chopstick[self.tno%numberOfThread]=ON_THE_TABLE
time.sleep(random.randint(1,2))
def run(self):
global chopstick
kount = 0
while restaurantOpen:
self.hungry()
self.eating()
kount +=1
self.drop()
self.think()
print self.tno,"I have already eaten for",kount,"times"


#define my Magic number
PRINT = 1 #Mean print all action
ON_THE_TABLE = 0 #Mean chopsticks is on the table
restaurantOpen = True
signal.signal(signal.SIGINT, handler)
action = PRINT
numberOfThread = setNumberOfThread()
chopstick = []
philosopher = []

for i in range(numberOfThread):
chopstick.append(ON_THE_TABLE)

print chopstick
print "Start call Tread"
for i in range(1,numberOfThread+1):
philosopher.append(Philosopher(i))
#run
for thrd in philosopher:
thrd.start()
#wait
while restaurantOpen:
time.sleep(random.randint(1,5))
print "Waiting for child"
#join
for thrd in philosopher:
thrd.join()

ไม่มีความคิดเห็น:

แสดงความคิดเห็น