gem-universe / blog

0 stars 0 forks source link

[操作系统]4. 建模操作系统 #4

Open supergem3000 opened 7 months ago

supergem3000 commented 7 months ago

4. Python 建模操作系统 (jyywiki.cn)

利用Python/Javascript语言特性,采用Generator函数,模拟操作系统的线程调度行为。 课程资料采用Python实现,我用Javascript模仿着实现一次。

type ThreadFuncGenerator = Generator<[syscall: string, args?: any[]]>

class Thread {
  func: ThreadFuncGenerator;
  retval: any;
  constructor(
    func: (...args: any[]) => ThreadFuncGenerator,
    ...args: any[]
  ) {
    this.func = func(args);
    this.retval = undefined;
  }

  step() {
    const result = this.func.next(this.retval);
    if (result.done) {
      throw new Error('Stop Iteration')
    };
    this.retval = undefined;
    return result.value
  }
}
class System {
  syscalls = ['choose', 'write', 'spawn', 'sched']
  main: (...args: any[]) => ThreadFuncGenerator

  constructor(src: string) {
    const main = eval(src);
    this.main = main;
  }

  run() {
    const threads = [new Thread(this.main)];
    const randomPointer = () => Math.floor(Math.random() * threads.length);
    let pointer = randomPointer();
    while (threads.length) {
      try {
        const t = threads[pointer];
        const [syscall, args] = t.step();
        switch (syscall) {
          case 'choose':
            t.retval = args![0][Math.floor(Math.random() * args![0].length)]
            break;
          case 'write':
            console.log(args![0]);
            break;
          case 'spawn':
            threads.push(new Thread(args![0], ...args!.slice(1)));
            break;
          case 'sched':
            pointer = randomPointer();
            break;
        }
      } catch (e) {
        threads.splice(pointer, 1);
        pointer = randomPointer();
      }
    }
  }
}

const start = (src: string) => {
  const os = new System(src);
  os.run();
}

start(`
const glob = { count: 0 };
function * t_print (name) {
  for (let i = 0; i < 3; i++) {
    glob.count += 1;
    yield ['write', [\`Hello from Thread \${name}: \${i + 1}\`]];
    yield ['sched'];
  }
}

function * main () {
  const n = yield ['choose', [[3, 4, 5]]];
  yield ['write', [\`#Thread = \${n}\`]];
  for (const name of ['a', 'b', 'c', 'd', 'e'].slice(0, n)) {
    yield ['spawn', [t_print, name]];
  }
  yield ['sched'];
}

main;
`)

Generator函数中的yield,将函数自己的控制权交给外界调用者。类比操作系统上应用程序的系统调用。