Найти - Пользователи
Полная версия: Помогите создать маленький симулятор
Начало » Центр помощи » Помогите создать маленький симулятор
1
Armany
Мне нужно создать симулятор который управляет 2 процессора. Выглядит примерно так:


Etape 1 -- b1 =  0      b2 = 0      
* CPU 1 * * CPU 2 *
==> 1 : if b2 != 1 then goto 3 ==> 1 : if b1 != 1 then goto 3
2 : goto 1 2 : goto 1
3 : b1 = 1 3 : b2 = 1
4 : Critical section 4 : Critical section
5 : b1 = 0 5 : b2 = 0

Give the number of CPU (1 or 2) 1
CPU 1 is executing
Etape 2 -- b1 = 0 b2 = 0
* CPU 1 * * CPU 2 *
1 : if b2 != 1 then goto 3 ==> 1 : if b1 != 1 then goto 3
2 : goto 1 2 : goto 1
==> 3 : b1 = 1 3 : b2 = 1
4 : Critical section 4 : Critical section
5 : b1 = 0 5 : b2 = 0
Give the number of CPU (1 or 2) 1
CPU 1 is executing
Etape 3 -- b1 = 1 b2 = 0
* CPU 1 * * CPU 2 *
1 : if b2 != 1 then goto 3 ==> 1 : if b1 != 1 then goto 3
2 : goto 1 2 : goto 1
3 : b1 = 1 3 : b2 = 1
==> 4 : Critical section 4 : Critical section
5 : b1 = 0 5 : b2 = 0
Give the number of CPU (1 or 2) 2
CPU 2 is executing
Etape 4 -- b1 = 1 b2 = 0
* CPU 1 * * CPU 2 *
1 : if b2 != 1 then goto 3 1 : if b1 != 1 then goto 3
2 : goto 1 ==> 2 : goto 1
3 : b1 = 1 3 : b2 = 1
==> 4 : Critical section 4 : Critical section
5 : b1 = 0 5 : b2 = 0
Give the number of CPU (1 or 2) 2
CPU 2 is executing
Etape 4 -- b1 = 1 b2 = 0
* CPU 1 * * CPU 2 *
1 : if b2 != 1 then goto 3 ==> 1 : if b1 != 1 then goto 3
2 : goto 1 2 : goto 1
3 : b1 = 1 3 : b2 = 1
==> 4 : Critical section 4 : Critical section
5 : b1 = 0 5 : b2 = 0


Если оба входят в критическую секцию одновременно то сообщение “Критическая секция нарушена”. Уже два дня пытаюсь никак не выходит помогите пожалуйста
s0rg
Странная система у нее получаются регистры b1 и b2 общие а instruction pointer - нет )
Ну как-то так, за час на коленке:

#-*- coding: utf8 -*-

import copy

class SmallJit(object):

class Jump(object):
def __init__(self, instr):
self._where = int(instr.split(' ')[1])

def run(self, regs):
regs['ip'] = self._where
return regs


class Condition(object):
def __init__(self, cond):
condarr = cond.split(' ')
self._reg = condarr[1]
self._cond = condarr[2]
self._val = int(condarr[3])
self._jump = SmallJit.Jump(' '.join(condarr[5:]))

def run(self, regs):
cond_true = False
if self._cond == '!=':
cond_true = bool(regs[self._reg] != self._val)
else:
raise RuntimeError('Bad condition: %s' % self._cond)

if cond_true:
regs = self._jump.run(regs)
else:
regs['ip'] += 1
return regs


class Move(object):
def __init__(self, instr):
a, b = instr.split('=')
self._dest = a.strip()
self._val = int(b.strip())

def run(self, regs):
regs[self._dest] = self._val
regs['ip'] += 1
return regs


class CriticalSection(object):
def __init__(self):
pass

def run(self, regs):
regs['ip'] += 1
return regs


def __init__(self, **regs):
self._regs = regs
self._regs['ip'] = 1
self._steps = dict()

def load(self, program):
for ln in program:
pos, inst = ln.split(':')
inst = inst.strip()
if inst.startswith('if'):
opcode = SmallJit.Condition(inst)
elif inst.startswith('goto'):
opcode = SmallJit.Jump(inst)
elif '=' in inst:
opcode = SmallJit.Move(inst)
elif inst == 'Critical section':
opcode = SmallJit.CriticalSection()
else:
raise RuntimeError('Bad instruction: %s' % inst)
self._steps[int(pos.strip())] = (opcode, inst)

def copy_regs(self, jit_to):
regs = copy.copy(self._regs)
del regs['ip']
jit_to.set_regs(regs)

def set_regs(self, regs):
for k, v in regs.iteritems():
self._regs[k] = v

def __get_cur_opcode(self):
step = self._regs['ip']
if step in self._steps:
opcode = self._steps[step][0]
return opcode
else:
raise RuntimeError('JIT terminated!')

def is_locked(self):
opcode = self.__get_cur_opcode()
return bool(isinstance(opcode, SmallJit.CriticalSection))

def do_step(self):
opcode = self.__get_cur_opcode()
self._regs = opcode.run(self._regs)

def __repr__(self):
result = ' '.join(['%s = %d'%(k, v) for k, v in self._regs.iteritems()])
result+= '\n' + '-' * 30 + '\n'
keys = sorted(self._steps.keys())
state = list()
for k in keys:
fmt = '=> %d : %s' if k == self._regs['ip'] \
else ' %d : %s'
state.append(fmt %(k, self._steps[k][1]))
result+= '\n'.join(state)
result+= '\n' + '-' * 30 + '\n'
return result


test_program1 = '''1 : if b2 != 1 then goto 3
2 : goto 1
3 : b1 = 1
4 : Critical section
5 : b1 = 0'''.split('\n')

test_program2 = '''1 : if b1 != 1 then goto 3
2 : goto 1
3 : b2 = 1
4 : Critical section
5 : b2 = 0'''.split('\n')

jit1 = SmallJit(b1=0, b2=0)
jit1.load(test_program1)

jit2 = SmallJit(b1=0, b2=0)
jit2.load(test_program2)

while 1:
jit1_stat = repr(jit1).split('\n')
jit2_stat = repr(jit2).split('\n')
padding = list()
for s in jit1_stat:
pad = 40 - len(s)
padding.append(' '*pad)

both = zip(jit1_stat, padding, jit2_stat)
print '\n'.join([''.join(a) for a in both])

if jit1.is_locked() and jit2.is_locked():
print 'LOCK ERROR!!!'
break

act = int(raw_input('Select CPU (1-2): '))
if act == 1:
jit1.do_step()
jit1.copy_regs(jit2)
elif act == 2:
jit2.do_step()
jit2.copy_regs(jit1)
else:
break
Armany
Спасибо кончено, ты здорово сделал но это еще далеко от моего уровня…Я попробовал по другому и единственная проблема в том что не получается циклить между первой и второй строчкой. Тоесть когда b1=1 a b2=0 или наоборот. Поможите исправить?
#!/usr/bin/python
# -*- coding: latin-1 -*-

import random
import time

b1=0
b2=0
sim= int(raw_input("Manual (1) or Auto (2) ? "))

def simple(sim,b1,b2):
crit = True
etape=1
k=0
p=0
fleche='==> '
s=' '
t1=[' ', ' ', ' ', ' ', ' ']
t2=[' ', ' ', ' ', ' ', ' ']
if crit is True:
l=['1: if b2 != 1 then goto 3','2: goto 1','3: b1 = 1','4: Critical section','5: b1 = 0']
m=['1: if b1 != 1 then goto 3','2: goto 1','3: b2 = 1','4: Critical section','5: b2 = 0']
print' ''* CPU 1 * * CPU 2 *'
for i in range(len(l)):
t1[0]=fleche
print t1[i],l[i].ljust(35,' '),' ',t1[i],m[i]
print ' ________________________________________________'
print '| Etape' ,etape, '-- b1 = ',b1, ' b2 =' ,b2,' |'
print '|________________________________________________|'
while crit is True:
etape+=1
if sim==1:
cpu=int(raw_input("Give the number of CPU (1 or 2) "))
if sim==2:
cpu=random.randint(1,2)
print 'CPU',cpu , 'execute instruction'
time.sleep(1)
print' ''* CPU 1 * * CPU 2 *'
if cpu == 1 :
k+=1
if cpu == 2:
p+=1
for i in range(len(m)):
f1=[' ', ' ', ' ', ' ', ' ']
f2=[' ', ' ', ' ', ' ', ' ']
f1[k]=fleche
f2[p]=fleche
if f1[3]==fleche :
b1=1
if f2[3]==fleche :
b2=1

if b2!=1 and k==1:
k=2
if b2==1 and k==1:
k=1

if b1!=1 and p==1:
p=2
if b1==1 and p==1:
p=1

if (f1[3]== fleche and f2[2]== fleche) or (f2[3]== fleche and f1[2]== fleche):
crit = False
break

print f1[i],l[i].ljust(35,' '),' ',f2[i],m[i]
print ' ________________________________________________'
print '| Etape' ,etape, '-- b1 = ',b1, ' b2 =' ,b2,' |'
print '|________________________________________________|'
if crit == False:
print 'Critical section disturbed !!'

simple(sim,b1,b2)
s0rg
Если я правильно понял, то вот этот ужас:
f1[k]=fleche
f2[p]=fleche
if f1[3]==fleche :
b1=1
if f2[3]==fleche :
b2=1
ответственнен за присвоение b1/b2. Если так то у вас выполняются присваивания на четвертом шаге - а не на третьем.
В Python как и во многих других я зыках используется 0-вой элемент как начало последовательности.
Armany
s0rg
Если я правильно понял, то вот этот ужас:
f1[k]=fleche
f2[p]=fleche
if f1[3]==fleche :
b1=1
if f2[3]==fleche :
b2=1
ответственнен за присвоение b1/b2. Если так то у вас выполняются присваивания на четвертом шаге - а не на третьем.
В Python как и во многих других я зыках используется 0-вой элемент как начало последовательности.
да нет это все правильно =) CPU должен выполнять инструкцию на следуещем шаге

и я решил проблему… добавил вот это
          if f1[2]==fleche and b2==1 and etape !=4:
f1[0]=fleche
f1[2]=s
k=0
if f2[2]==fleche and b1==1 and etape !=4:
f2[0]=fleche
f2[2]=s
p=0
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB