操作系统

作业

多道程序运行模拟

F#

open System
open System.Threading
open System.Collections.Generic

//线程
type PrElement =
    | Normal of (int * string * int) list
    | Null

let rate = 100 //与真实时间的比例
let mutable pool = [] //线程池
let mutable suspend = 0 //挂起的线程
let mutable IOSystemWork = false //io工作状态
let Processor = new Queue<Async<unit>>() //处理队列
let IOSystem = new Queue<Thread>() //io队列
let Argslize = String.concat " "
let PrintArgs x = "[" + DateTime.Now.ToString() + "] " + Argslize x |> Console.WriteLine

//改变线程池状态的消息队列
let SetPool = 
    new MailboxProcessor<int * PrElement * AsyncReplyChannel<string>>(fun x ->
        let rec loop count = 
            async{
                let! i, v, r = x.Receive()
                let tpool = Array.ofList pool
                tpool.[i] <- v
                pool <- List.ofArray tpool
                r.Reply ""
                return! loop (count + 1)
            }
        loop 0)

//输入线程
let rec Input count =
    match Console.ReadLine().Trim().ToLower() with
    | s when s <> "" -> 
        (s.Split ' '
        |> List.ofArray
        |> List.map (fun i -> 
            let temp = List.ofArray <| i.Split ','
            count, temp.[0], Convert.ToInt32 temp.[1]))::Input (count + 1)
    | _ -> []

//获取线程id
let GetPid p =
    let pid, _, _ = p
    pid

//获取类型
let GetStatus p =
    let _, status, _ = p
    status

//检查线程是否为null
let toPrElement (r : (int * string * int) list) =
    match r.Length with
    | 0 -> Null
    | _ -> Normal r

//处理线程池
let Process _ =
    //获取可处理的io
    let rec GetIO (po : PrElement list) =
        match po with
        | Normal(p)::_ when GetStatus p.Head = "io" ->
            let iosp::iospt = p
            IOSystemWork <- true
            let pid, _, time = iosp
            SetPool.PostAndReply(fun reply -> pid - 1, toPrElement iospt, reply) |> ignore
            suspend <- pid
            IOSystem.Enqueue(
                new Thread(new ThreadStart(fun _ ->
                    ["process"; pid.ToString(); "io"; time.ToString(); "start"] |> PrintArgs
                    Thread.Sleep(time * rate)
                    IOSystemWork <- false
                    suspend <- 0
                    ["process"; pid.ToString(); "io"; time.ToString(); "end"] |> PrintArgs
                )))
        | _::pt -> GetIO pt
        | _ -> ()
    //处理线程
    let sub = function
        | Normal p ->
            match p with
            | sp::spt when GetStatus sp = "p" && GetPid sp <> suspend ->
                let pid, _, time = sp
                Processor.Enqueue(
                    async{
                        ["process"; pid.ToString(); "subprocess"; time.ToString(); "start"] |> PrintArgs
                        Thread.Sleep(time * rate)
                        ["process"; pid.ToString(); "subprocess"; time.ToString(); "end"] |> PrintArgs
                    })
                if not IOSystemWork then
                    GetIO pool
                    if IOSystem.Count > 0 then
                        IOSystem.Dequeue().Start()
                Console.WriteLine()
                SetPool.PostAndReply(fun reply -> pid - 1, toPrElement spt, reply) |> ignore
                Processor.Dequeue() |> Async.RunSynchronously
                match pool 
                    |> List.filter (fun x -> 
                        match x with
                        | Normal _ -> true
                        | _ -> false)
                    |> List.length with
                | 0 ->
                    Console.Write "请按任意键继续. . ."
                    Console.ReadLine() |> ignore
                    exit 0
                | _ -> true
            | _ -> false
        | _ -> false
    //主循环
    let rec loop = function
        | p::_ when sub p -> loop pool
        | _::pt -> loop pt
        | _ -> loop pool
    loop pool
    
//入口
[<STAThread>]
[<EntryPoint>]
let rec main _ =
    try
        let rec input12 _ =
            Console.Write "1.抢占/2.非抢占:"
            match Console.ReadLine().Trim() with
            | "1" -> FScpp.FS() |> ignore
            | "2" -> 
                Console.WriteLine "示例(p=cpu处理, io=使用io (单位:s))\n按优先级从高到底输入\n输入空行=结束输入\np,30 io,40 p,10\np,60 io,30 p,10\np,20 io,40 p,20\n------------------------\n"
                SetPool.Start()
                pool <- Input 1 |> List.map Normal
                Process()
            | _ -> input12()
        input12()
        0
    with
    | _ ->
        Console.WriteLine "Exm???????"
        main [|String.Empty|]

C++/CLI

#include "stdafx.h"

#include "FScpp.h"

#include <cstdio>
#include <cstdlib>

struct progress
{
	int runtime1;
	int iotime;
	int runtime2;
};

namespace FScpp
{
	FS::FS()
	{
		int count;
		int i = 0, flag = 0, flag2 = 0, rest[100];
		const auto time = 0;
		struct progress f[100], s[100];
		printf("请输入进程个数(2-24)并且按照优先级从高到低依次输入\n");
		scanf("%d", &count);
		while (i < count)
		{
			printf("进程计算时长1,I/O操作时长,进程计算时长");
			scanf("%d", &f[i].runtime1);
			scanf("%d", &f[i].iotime);
			scanf("%d", &f[i].runtime2);
			i++;
		}
		printf("----------多道抢占式调度算法----------\n");
		for (i = 0; i < count; i++)
		{
			//此处是第一的程序的执行情况 
			if (flag == 0)
			{
				s[i].runtime1 = time + f[i].runtime1;
				printf("从%dms到%dms程序%d在CPU上运行\n", time, s[i].runtime1, i);
				s[i].iotime = s[i].runtime1 + f[i].iotime;
				printf("从%dms到%dms程序%d在I/O上运行\n", s[i].runtime1, s[i].iotime, i);
				s[i].runtime2 = s[i].iotime + f[i].runtime2;
				printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
				flag = 1;
			}
			//接下来是出去第一个进程的运行情况 
			else
			{
				if (f[i].runtime1 > f[i - 1].iotime&&flag2 == 0)
				{
					s[i].runtime1 = s[i - 1].runtime1 + f[i - 1].iotime;
					printf("从%dms到%dms程序%d在CPU上运行,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].runtime1, s[i].runtime1, i, i, i - 1);
					rest[i] = f[i].runtime1 - f[i - 1].iotime;
					s[i].runtime1 = s[i - 1].runtime2 + rest[i];
					printf("从%dms到%dms程序%d在CPU上运行\n", s[i - 1].runtime2, s[i].runtime1, i);
					s[i].iotime = s[i].runtime1 + f[i].iotime;
					printf("从%dms到%dms程序%d进行I/O操作\n", s[i].runtime1, s[i].iotime, i);
					s[i].runtime2 = s[i].iotime + f[i].runtime2;
					printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
				}
				else if (f[i].runtime1 <= f[i - 1].iotime&&flag2 == 0)
				{
					s[i].runtime1 = s[i - 1].runtime1 + f[i].runtime1;
					printf("从%dms到%dms程序%d在CPU上运行,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].runtime1, s[i].runtime1, i, i, i - 1);
					s[i].iotime = s[i - 1].iotime + f[i].iotime;
					printf("从%dms到%dms程序%d进行I/O操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].iotime, s[i].iotime, i, i - 1, i);
					s[i].runtime2 = s[i].iotime + f[i].runtime2;
					printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
					rest[i] = f[i - 1].iotime - f[i].runtime1;
					flag2 = 1;
				}
				else if (rest[i - 1] < f[i].runtime1&&flag2 != 0)
				{
					s[i].runtime1 = s[i - 1].runtime1 + rest[i - 1];
					printf("从%dms到%dms程序%d进行CPU操作\n", s[i - 1].runtime1, s[i].runtime1, i);
					rest[i] = f[i].runtime1 - rest[i - 1];
					if (rest[i - 1] >= s[i].runtime1)
					{
						printf("此时%d的CPU运算与%d的I/O同时运行", i, i - 3);
					}
					else
					{
						printf("此时%d的CPU运算与%d的I/O同时运行", i, i - 2);
					}
					if (f[i - 3].iotime - f[i - 2].runtime1 - f[i - 1].runtime1 - rest[i - 1] >= 0)
					{
						s[i].runtime1 = s[i - 3].runtime2 + rest[i];
						printf("从%dms到%dms程序%d进行CPU操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 3].runtime2, s[i].runtime1, i, i, i - 2);
					}
					else
					{
						s[i].runtime1 = s[i - 2].runtime2 + rest[i];
						printf("从%dms到%dms程序%d进行CPU操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 2].runtime2, s[i].runtime1, i, i, i - 1);
					}
					if (s[i].runtime1 > s[i - 1].iotime)
					{
						int a = s[i].runtime1 - s[i - 1].iotime;
						printf("从%dms到%dms程序%d进行CPU操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 2].runtime2, s[i - 1].iotime, i, i, i - 1);
						s[i].runtime1 = s[i - 1].runtime2 + a;
						printf("从%dms到%dms程序%d进行CPU操作\n", s[i - 1].runtime2, s[i].runtime1, i);
						s[i].iotime = s[i].runtime1 + f[i].iotime;
						printf("从%dms到%dms程序%d进行I/O操作\n", s[i].runtime1, s[i].iotime, i);
						if (f[i - 1].runtime2 > f[i].iotime)
						{
							s[i].runtime2 = s[i - 1].runtime2 + f[i].runtime2;
							printf("从%dms到%dms程序%d进行CPU操作\n", s[i - 1].runtime2, s[i].runtime2, i);
						}
						else
						{
							s[i].runtime2 = s[i].iotime + f[i].runtime2;
							printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
						}
						flag2 = 1;
					}
					else
					{

						s[i].iotime = s[i - 1].iotime + f[i].iotime;
						printf("从%dms到%dms程序%d进行I/O操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].iotime, s[i].iotime, i, i - 1, i);
						if (f[i - 1].runtime2 > f[i].iotime)
						{
							s[i].runtime2 = s[i - 1].runtime2 + f[i].runtime2;
							printf("从%dms到%dms程序%d进行CPU操作\n", s[i - 1].runtime2, s[i].runtime2, i);
						}
						else
						{
							s[i].runtime2 = s[i].iotime + f[i].runtime2;
							printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
						}
						flag2 = 1;
					}
				}
				else if (rest[i - 1] > f[i].runtime1&&flag2 != 0)
				{
					s[i].runtime1 = s[i - 1].runtime1 + f[i].runtime1;
					rest[i] = rest[i - 1] - f[i].runtime1;
					printf("从%dms到%dms程序%d进行CPU操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].runtime1, s[i].runtime1, i, i, i - 2);
					s[i].iotime = s[i - 1].iotime + f[i].iotime;
					printf("从%dms到%dms程序%d进行I/O操作,此时%d的CPU运算与%d的I/O同时运行\n", s[i - 1].iotime, s[i].iotime, i, i - 1, i);
					if (f[i - 1].runtime2 > f[i].iotime)
					{
						s[i].runtime2 = s[i - 1].runtime2 + f[i].runtime2;
						printf("从%dms到%dms程序%d进行CPU操作\n", s[i - 1].runtime2, s[i].runtime2, i);
					}
					else
					{
						s[i].runtime2 = s[i].iotime + f[i].runtime2;
						printf("从%dms到%dms程序%d进行CPU操作\n", s[i].iotime, s[i].runtime2, i);
					}
				}
			}
		}
		system("pause");
	}
}

文件系统实验

F#

open Fuck
open System

//文件系统
type Tree = 
    | Node of list<string * Tree>
    | Leaf of File

//创建文件
let touch disk cpath filename =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> Node[dht,Node([(filename,Leaf(new File(filename)))]@dhn)]
        | Node((dht,Node(dhn))::_),(ph::pt) when ph = dht -> match loop (Node(dhn)) pt with | Node(x) -> Node((ph,Node(dhn))::x)
        | Node(h::t),_ -> match loop (Node(t)) p with | Node(x) -> Node(h::x)
    loop disk cpath

//删除文件
let rm disk cpath filename =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> Node[dht,Node(dhn |> List.filter (fun x -> fst x <> filename))]
        | Node((dht,Node(dhn))::t),(ph::pt) when p.Head = dht -> match loop (Node(t)) pt with | Node(x) -> Node((ph,Node(dhn))::x)
        | Node(h::t),_ -> match loop (Node(t)) p with | Node(x) -> Node(h::x)
    loop disk cpath

//打开文件
let fopen disk cpath filename user =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> match (snd (dhn |> List.filter (fun x -> fst x = filename)).Head) with | Leaf(f) -> f.Open(user)
        | Node((dht,Node(dhn))::_),(_::pt) when p.Head = dht -> loop (Node(dhn)) pt
        | Node(_::t),_ -> loop (Node(t)) p
    loop disk cpath

//关闭文件
let fclose disk cpath filename user =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> match (snd (dhn |> List.filter (fun x -> fst x = filename)).Head) with | Leaf(f) -> f.Close(user)
        | Node((dht,Node(dhn))::_),(_::pt) when p.Head = dht -> loop (Node(dhn)) pt
        | Node(_::t),_ -> loop (Node(t)) p
    loop disk cpath

//读取文件
let read disk cpath filename user offset =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> match (snd (dhn |> List.filter (fun x -> fst x = filename)).Head) with | Leaf(f) -> f.Read(user, offset)
        | Node((dht,Node(dhn))::_),(_::pt) when p.Head = dht -> loop (Node(dhn)) pt
        | Node(_::t),_ -> loop (Node(t)) p
    loop disk cpath

//写入文件
let write disk cpath filename user data =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> match (snd (dhn |> List.filter (fun x -> fst x = filename)).Head) with | Leaf(f) -> f.Write(user, data)
        | Node((dht,Node(dhn))::_),(_::pt) when p.Head = dht -> loop (Node(dhn)) pt
        | Node(_::t),_ -> loop (Node(t)) p
    loop disk cpath

//列出文件和目录
let ls disk cpath =
    let rec loop d p =
        match d,p with
        | Node((dht, Node(dhn))::_),(ph::[]) when ph = dht -> dhn |> List.iter (fun x -> fst x |> Console.WriteLine)
        | Node((dht,Node(dhn))::_),(ph::pt) when ph = dht -> loop (Node(dhn)) pt
        | Node(_::t),_ -> loop (Node(t)) p
    loop disk cpath

//设置用户文件状态
let rec setFilename user filename = function
    | (u, _)::t when u = user -> (u, filename)::t
    | h::t -> h::setFilename user filename t

//读取用户文件状态
let rec getFilename user = function
    | (u,f)::_ when u = user -> f
    | _::t -> getFilename user t

//主循环
let rec system users user disk cpath =
    Console.Write "->"
    match Console.ReadLine().Split(' ') |> List.ofArray with
    | "touch"::f::[] ->
        system users user (touch disk cpath f) cpath
    | "rm"::f::[] -> system users user (rm disk cpath f) cpath
    | "open"::f::[] when getFilename user users = "" && fopen disk cpath f user -> system (setFilename user f users) user disk cpath
    | "close"::f::[] when getFilename user users = f ->
        fclose disk cpath f user
        system (setFilename user "" users) user disk cpath
    | "read"::f::o::[] when getFilename user users = f ->
        read disk cpath f user (Int32.Parse o)
        system users user disk cpath
    | "write"::f::d::[] when getFilename user users = f ->
        write disk cpath f user d
        system users user disk cpath
    | "ls"::[] ->
        ls disk cpath
        system users user disk cpath
    | "cd"::".."::[] -> system users user disk (cpath |> List.take (cpath.Length - 1))
    | "cd"::d::[] -> system users user disk (cpath@[d])
    | "su"::u::[] -> system users u disk cpath
    | "useradd"::u::[] -> system ((u, "")::users) user disk cpath
    | "whoami"::[] -> 
        Console.WriteLine user
        system users user disk cpath
    | "pwd"::[] -> 
        cpath |> List.reduce (fun a b -> a + "/" + b) |> Console.WriteLine
        system users user disk cpath
    | [] -> 
        Console.WriteLine()
        system users user disk cpath
    | e -> 
        Console.WriteLine("Command '" + (List.reduce (fun a b -> a + " " + b) e) + "' not found")
        system users user disk cpath

//入口
[<STAThread>]
[<EntryPoint>]
let main _ = 
    let disk =
        Node["root", Node[
            "someFile.txt", Leaf(new File("someFile.txt", "some content"));
            "aFile.txt", Leaf(new File("aFile.txt", "some content"));
            "someDir", Node[ 
                "anotherFile.txt", Leaf(new File("anotherFile.txt", "more content"));
                "script.sh", Leaf(new File("script.sh", "script content"))];
            "logfile.log", Leaf(new File("logfile.log", "log content"));
            "otherDir", Node[ 
                "otheranotherFile.txt", Leaf(new File("otheranotherFile.txt", "more content"));
                "otherscript.sh", Leaf(new File("otherscript.sh", "script content"))];
            "otherlogfile.log", Leaf(new File("otherlogfile.log", "log content"))]]
    system ["root", ""] "root" disk ["root"]
    0

C++/CLI

#include "stdafx.h"

namespace Fuck
{
	public ref class File
	{
	public:
		System::String^ User = "";
		System::Collections::Generic::List<System::Char>^ Data = gcnew System::Collections::Generic::List<System::Char>();
		System::String^ Path = "";
		int index;
		File(System::String^ path)
		{
			Path = path;
		}
		File(System::String^ path, System::String^ data)
		{
			Path = path;
			index = 0;
			for (auto i = 0; i < data->Length; ++i) Data->Add(data[i]);
		}
		bool Open(System::String^ user)
		{
			if (User == "")
			{
				User = user;
				index = 0;
				return true;
			}
			System::Console::WriteLine("E: Could not open file " + Path);
			return false;
		}
		void Close(System::String^ user)
		{
			if (User == user) User = "";
			else System::Console::WriteLine("E: Could not close file " + Path);
		}
		void Read(System::String^ user, const int offset)
		{
			if (User == user)
			{
				for (auto i = index; index < Data->Count && i < offset; ++index, ++i) System::Console::Write(Data[index]);
			}
			else
			{
				System::Console::Write("E: Could not read file " + Path);
			}
			System::Console::WriteLine();
		}
		void Write(System::String^ user, System::String^ data)
		{
			if (User == user)
			{
				for (auto i = 0; i < data->Length; ++i, ++index)
				{
					if (index < Data->Count) Data[index] = data[i];
					else Data->Add(data[i]);
				}
			}
			else
			{
				System::Console::WriteLine("E: Could not write file " + Path);
			}
		}
	};
}

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注