国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

這篇具有很好參考價(jià)值的文章主要介紹了哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、實(shí)驗(yàn)內(nèi)容

  • 基于模板?process.c?編寫多進(jìn)程的樣本程序,實(shí)現(xiàn)如下功能: + 所有子進(jìn)程都并行運(yùn)行,每個(gè)子進(jìn)程的實(shí)際運(yùn)行時(shí)間一般不超過 30 秒; + 父進(jìn)程向標(biāo)準(zhǔn)輸出打印所有子進(jìn)程的 id,并在所有子進(jìn)程都退出后才退出;
  • 在?Linux0.11?上實(shí)現(xiàn)進(jìn)程運(yùn)行軌跡的跟蹤。 + 基本任務(wù)是在內(nèi)核中維護(hù)一個(gè)日志文件?/var/process.log,把從操作系統(tǒng)啟動(dòng)到系統(tǒng)關(guān)機(jī)過程中所有進(jìn)程的運(yùn)行軌跡都記錄在這一 log 文件中。
  • 在修改過的 0.11 上運(yùn)行樣本程序,通過分析 log 文件,統(tǒng)計(jì)該程序建立的所有進(jìn)程的等待時(shí)間、完成時(shí)間(周轉(zhuǎn)時(shí)間)和運(yùn)行時(shí)間,然后計(jì)算平均等待時(shí)間,平均完成時(shí)間和吞吐量??梢宰约壕帉懡y(tǒng)計(jì)程序,也可以使用 python 腳本程序——?stat_log.py(在?/home/teacher/?目錄下) ——進(jìn)行統(tǒng)計(jì)。
  • 修改 0.11 進(jìn)程調(diào)度的時(shí)間片,然后再運(yùn)行同樣的樣本程序,統(tǒng)計(jì)同樣的時(shí)間數(shù)據(jù),和原有的情況對(duì)比,體會(huì)不同時(shí)間片帶來的差異。

/var/process.log?文件的格式必須為:

PID     X       Time

其中:

  • pid 是進(jìn)程的 ID;
  • X 可以是 N、J、R、W 和 E 中的任意一個(gè),分別表示進(jìn)程新建(N)、進(jìn)入就緒態(tài)(J)、進(jìn)入運(yùn)行態(tài)(R)、進(jìn)入阻塞態(tài)(W) 和退出(E);
  • time 表示 X 發(fā)生的時(shí)間。這個(gè)時(shí)間不是物理時(shí)間,而是系統(tǒng)的滴答時(shí)間(tick);

三個(gè)字段之間用制表符分隔。例如:

12    N    1056
12    J    1057
4    W    1057
12    R    1057
13    N    1058
13    J    1059
14    N    1059
14    J    1060
15    N    1060
15    J    1061
12    W    1061
15    R    1061
15    J    1076
14    R    1076
14    E    1076
......

二、實(shí)驗(yàn)環(huán)境搭建(Ubuntu虛擬機(jī))

ubuntu下 Linux 0.11 編譯內(nèi)核 - 實(shí)驗(yàn)環(huán)境搭建_~橘子~的博客-CSDN博客如果想學(xué)習(xí)Linux 0.11,實(shí)驗(yàn)環(huán)境是必不可少的。最好是能編譯,能運(yùn)行,能調(diào)試。本文用的是Mooc網(wǎng)上的哈工大李治軍老師操作系統(tǒng)!李老師的講課風(fēng)格淺入深出。1.下載Linux 0.11用github下載https://github.com/Wangzhike/HIT-Linux-0.11 下載命令行下載 如果沒有g(shù)it,那么先安裝gitsudo apt-get instal...https://blog.csdn.net/qq_39557240/article/details/85336730

三、先備知識(shí)

在init/目錄下有一個(gè)main.c文件,系統(tǒng)在執(zhí)行完boot/目錄下的head.s程序后就會(huì)將執(zhí)行權(quán)交給main.c,這個(gè)程序包含了內(nèi)核初始化的所有工作。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

  • 多進(jìn)程如何啟動(dòng)?

?main中的fork()創(chuàng)建了操作系統(tǒng)中的0進(jìn)程的第一個(gè)子進(jìn)程,在這個(gè)子進(jìn)程中,執(zhí)行了init(),init中又執(zhí)行了Shell(Windows桌面),Shell這個(gè)進(jìn)程再啟動(dòng)其他進(jìn)程,這樣就形成了多進(jìn)程圖像。

這里簡單介紹一下fork()函數(shù),fork()系統(tǒng)調(diào)用用于創(chuàng)建子進(jìn)程,它的返回值有兩個(gè),父進(jìn)程返回創(chuàng)建子進(jìn)程的pid,子進(jìn)程返回0。這里if(!fork())就表示在子進(jìn)程中調(diào)用init()函數(shù)。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

  • 多進(jìn)程如何組織?

多進(jìn)程的組織依賴于一些重要的數(shù)據(jù)結(jié)構(gòu),比如PCB(進(jìn)程控制塊)、隊(duì)列和狀態(tài)。

進(jìn)程控制塊(PCB):是用來記錄進(jìn)程信息的一種數(shù)據(jù)結(jié)構(gòu),它在linux-0.11內(nèi)核中的include/linux/sched.h中,結(jié)構(gòu)如下:

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

狀態(tài):這里值進(jìn)程的狀態(tài),進(jìn)程的狀態(tài)有五種:新建態(tài)、就緒態(tài)、運(yùn)行態(tài)、阻塞態(tài)、終止態(tài)。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?注:上面的箭頭表示狀態(tài)的轉(zhuǎn)換方向

隊(duì)列:因?yàn)镃PU在同一時(shí)刻只能運(yùn)行一個(gè)進(jìn)程。除了處于運(yùn)行態(tài)的進(jìn)程,其他的進(jìn)程都排隊(duì)等著執(zhí)行。

????????但是每個(gè)進(jìn)程的狀態(tài)又是不一樣的,如果進(jìn)程已經(jīng)準(zhǔn)備就緒,只是還沒有被分配CPU,這個(gè)進(jìn)程的PCB就處于就緒隊(duì)列上,等著被CPU調(diào)度。如果進(jìn)程正在等待一個(gè)事件發(fā)生,從而發(fā)生了阻塞,需要這個(gè)事件發(fā)生來喚醒,那么這個(gè)進(jìn)程PCB處于阻塞隊(duì)列上,等著被喚醒,喚醒后則進(jìn)入就緒態(tài)。

因此每個(gè)隊(duì)列上的元素都是進(jìn)程的PCB,隨著進(jìn)程狀態(tài)的改變,這些PCB也會(huì)隨之出隊(duì)入隊(duì)。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

這樣操作系統(tǒng)就把多個(gè)進(jìn)程有序的組織起來了。

  • 多進(jìn)程如何交替?

進(jìn)程交替需要三個(gè)步驟:隊(duì)列操作+調(diào)度+切換

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?隊(duì)列操作:就是將進(jìn)程PCB放入對(duì)應(yīng)狀態(tài)的等待隊(duì)列中,隨著進(jìn)程狀態(tài)轉(zhuǎn)換出隊(duì)入隊(duì)的操作。

調(diào)度:當(dāng)一個(gè)進(jìn)程因?yàn)橐却硞€(gè)事件的發(fā)生(比如讀寫磁盤的IO操作)或者時(shí)間片用完,擦偶作系統(tǒng)會(huì)使用剝奪當(dāng)前進(jìn)程的CPU使用權(quán),使用調(diào)度算法(FIFO、短作業(yè)優(yōu)先等策略)在就緒隊(duì)列中選出下一個(gè)進(jìn)程使用CPU。

切換:當(dāng)進(jìn)程切換時(shí),需要保存運(yùn)行時(shí)的一些狀態(tài)和數(shù)據(jù),而這些都保存在CPU的寄存器中,這時(shí),被剝奪CPU的進(jìn)程需要把CPU這些寄存器的值保存在自己的PCB中,而獲得CPU使用權(quán)的進(jìn)程,為了從上次運(yùn)行的狀態(tài)繼續(xù)運(yùn)行,則需要將自己PCB中的寄存器的值賦值給CPU。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

  • 多進(jìn)程如何影響?

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?實(shí)驗(yàn)相關(guān)源碼分析:

1.實(shí)驗(yàn)?zāi)康氖且獙⑦M(jìn)程的每一次狀態(tài)變換和該狀態(tài)持續(xù)的時(shí)間都記錄在log文件中,因此要求操作系統(tǒng)啟動(dòng)后先打開/var/process.log,然后就可以在每個(gè)進(jìn)程發(fā)生狀態(tài)切換的時(shí)候?qū)懭胗涗?,為了能盡早開始記錄,應(yīng)該在內(nèi)核啟動(dòng)時(shí)就打開log文件,內(nèi)核入口是init/main.c的main函數(shù):

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

將下面紅色區(qū)域的代碼剪切到上面 move_to_user_mode();后面,然后其后跟著添加打開log文件的代碼:

(void) open("/var/process.log",O_CREAT|O_TRUNC|O_WRONLY,0666);

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?這樣,文件描述符0,1,2,3就在進(jìn)程0中創(chuàng)建了。根據(jù)fork()原理,進(jìn)程0創(chuàng)建的任意子進(jìn)程都會(huì)繼承這些文件描述符,因此在init()中就不必再open()了。此后,init()的后續(xù)代碼和/bin/sh都會(huì)重新初始化它們。所以只有進(jìn)程0和進(jìn)程1的文件描述符關(guān)聯(lián)著log文件。

2.編寫fprintk()函數(shù),所有的狀態(tài)轉(zhuǎn)移都是在內(nèi)核環(huán)境下發(fā)生的,而想要把每一次狀態(tài)切換的記錄寫入log文件,內(nèi)核不能使用write()函數(shù),就像內(nèi)核狀態(tài)下只能調(diào)用printk()而不能調(diào)用printf()函數(shù)一樣。因此這個(gè)fprintk()函數(shù)實(shí)現(xiàn)的功能就是在內(nèi)核中寫log文件。下面是代碼:

#include "linux/sched.h"
#include "sys/stat.h"

static char logbuf[1024];
int fprintk(int fd, const char *fmt, ...)
{
    va_list args;
    int count;
    struct file * file;
    struct m_inode * inode;

    va_start(args, fmt);
    count=vsprintf(logbuf, fmt, args);
    va_end(args);
/* 如果輸出到stdout或stderr,直接調(diào)用sys_write即可 */
    if (fd < 3)
    {
        __asm__("push %%fs\n\t"
            "push %%ds\n\t"
            "pop %%fs\n\t"
            "pushl %0\n\t"
        /* 注意對(duì)于Windows環(huán)境來說,是_logbuf,下同 */
            "pushl $logbuf\n\t"
            "pushl %1\n\t"
        /* 注意對(duì)于Windows環(huán)境來說,是_sys_write,下同 */
            "call sys_write\n\t"
            "addl $8,%%esp\n\t"
            "popl %0\n\t"
            "pop %%fs"
            ::"r" (count),"r" (fd):"ax","cx","dx");
    }
    else
/* 假定>=3的描述符都與文件關(guān)聯(lián)。事實(shí)上,還存在很多其它情況,這里并沒有考慮。*/
    {
    /* 從進(jìn)程0的文件描述符表中得到文件句柄 */
        if (!(file=task[0]->filp[fd]))
            return 0;
        inode=file->f_inode;

        __asm__("push %%fs\n\t"
            "push %%ds\n\t"
            "pop %%fs\n\t"
            "pushl %0\n\t"
            "pushl $logbuf\n\t"
            "pushl %1\n\t"
            "pushl %2\n\t"
            "call file_write\n\t"
            "addl $12,%%esp\n\t"
            "popl %0\n\t"
            "pop %%fs"
            ::"r" (count),"r" (file),"r" (inode):"ax","cx","dx");
    }
    return count;
}

?3.在進(jìn)程狀態(tài)切換處,將進(jìn)程的聲明周期寫入日志。涉及到的文件有fork.c、sched.c、exit.c

新建態(tài):用戶使用fork()函數(shù),新建的進(jìn)程處于新建態(tài)

就緒態(tài):進(jìn)程新建之后進(jìn)入就緒態(tài)、進(jìn)程阻塞事件發(fā)生進(jìn)入就緒態(tài)、進(jìn)程時(shí)間片用完進(jìn)入就緒態(tài)等等

阻塞態(tài):進(jìn)程等待資源或事件會(huì)進(jìn)入阻塞態(tài)

運(yùn)行態(tài):進(jìn)程被調(diào)度占用CPU進(jìn)入運(yùn)行態(tài)

?四、實(shí)驗(yàn)步驟

?1.修改init.c文件。

將init.c文件中的init()的以下代碼移動(dòng)到main()函數(shù)中,并添加代碼打開process.log文件。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

2.在printf.c里面添加上面fprintk的代碼:

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

3.將進(jìn)程狀態(tài)切換信息寫入process.log文件:

修改fork文件:

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

修改sched.c文件:

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?4.在linux-0.11目錄下執(zhí)行make all重新編譯,若沒報(bào)錯(cuò)則執(zhí)行下一步。

5.編寫process.c文件,這個(gè)文件可以放在oslab下,為了把這個(gè)文件拷貝到linux-0.11系統(tǒng)中,需要掛載系統(tǒng)硬盤,最后啟動(dòng)linux-0.11系統(tǒng),在這個(gè)系統(tǒng)里編譯運(yùn)行process.c文件。

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/times.h>

#define HZ	100

void cpuio_bound(int last, int cpu_time, int io_time);

int main(int argc, char * argv[])
{
	pid_t n_proc[10]; /*10個(gè)子進(jìn)程 PID*/
	int i;
	for(i=0;i<10;i++)
	{
		n_proc[i] = fork();
		/*子進(jìn)程*/
		if(n_proc[i] == 0)
		{
			cpuio_bound(20,2*i,20-2*i); /*每個(gè)子進(jìn)程都占用20s*/
			return 0; /*執(zhí)行完cpuio_bound 以后,結(jié)束該子進(jìn)程*/
		}
		/*fork 失敗*/
		else if(n_proc[i] < 0 )
		{
			printf("Failed to fork child process %d!\n",i+1);
			return -1;
		}
		/*父進(jìn)程繼續(xù)fork*/
	}
	/*打印所有子進(jìn)程PID*/
	for(i=0;i<10;i++)
		printf("Child PID: %d\n",n_proc[i]);
	/*等待所有子進(jìn)程完成*/
	wait(&i);  /*Linux 0.11 上 gcc要求必須有一個(gè)參數(shù), gcc3.4+則不需要*/ 
	return 0;
}

/*
 * 此函數(shù)按照參數(shù)占用CPU和I/O時(shí)間
 * last: 函數(shù)實(shí)際占用CPU和I/O的總時(shí)間,不含在就緒隊(duì)列中的時(shí)間,>=0是必須的
 * cpu_time: 一次連續(xù)占用CPU的時(shí)間,>=0是必須的
 * io_time: 一次I/O消耗的時(shí)間,>=0是必須的
 * 如果last > cpu_time + io_time,則往復(fù)多次占用CPU和I/O
 * 所有時(shí)間的單位為秒
 */
void cpuio_bound(int last, int cpu_time, int io_time)
{
	struct tms start_time, current_time;
	clock_t utime, stime;
	int sleep_time;

	while (last > 0)
	{
		/* CPU Burst */
		times(&start_time);
		/* 其實(shí)只有t.tms_utime才是真正的CPU時(shí)間。但我們是在模擬一個(gè)
		 * 只在用戶狀態(tài)運(yùn)行的CPU大戶,就像“for(;;);”。所以把t.tms_stime
		 * 加上很合理。*/
		do
		{
			times(&current_time);
			utime = current_time.tms_utime - start_time.tms_utime;
			stime = current_time.tms_stime - start_time.tms_stime;
		} while ( ( (utime + stime) / HZ )  < cpu_time );
		last -= cpu_time;

		if (last <= 0 )
			break;

		/* IO Burst */
		/* 用sleep(1)模擬1秒鐘的I/O操作 */
		sleep_time=0;
		while (sleep_time < io_time)
		{
			sleep(1);
			sleep_time++;
		}
		last -= sleep_time;
	}
}

掛載代碼:sudo ./mount-hdc

將process文件用cp指令復(fù)制到hdc/usr/root目錄下,然后在oslab目錄執(zhí)行./run,啟動(dòng)系統(tǒng)。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)?執(zhí)行process之后,會(huì)生成log文件(這個(gè)文件在hdc/var目錄下,退出linux-0.11,hdc會(huì)自動(dòng)卸載,再掛載一次就行了),但注意一定要刷新,然后將log文件拷貝到oslab目錄下。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?6.編寫python文件stat_log.py(這個(gè)文件放在oslab下),統(tǒng)計(jì)進(jìn)程的運(yùn)行信息。

#!/usr/share/python
import sys
import copy

P_NULL = 0
P_NEW = 1
P_READY = 2
P_RUNNING = 4
P_WAITING = 8
P_EXIT = 16

S_STATE = 0
S_TIME = 1

HZ = 100

graph_title = r"""
-----===< COOL GRAPHIC OF SCHEDULER >===-----

             [Symbol]   [Meaning]
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~
             number   PID or tick
              "-"     New or Exit 
              "#"       Running
              "|"        Ready
              ":"       Waiting
                    / Running with 
              "+" -|     Ready 
                    \and/or Waiting

-----===< !!!!!!!!!!!!!!!!!!!!!!!!! >===-----
"""

usage = """
Usage: 
%s /path/to/process.log [PID1] [PID2] ... [-x PID1 [PID2] ... ] [-m] [-g]

Example:
# Include process 6, 7, 8 and 9 in statistics only. (Unit: tick)
%s /path/to/process.log 6 7 8 9

# Exclude process 0 and 1 from statistics. (Unit: tick)
%s /path/to/process.log -x 0 1

# Include process 6 and 7 only and print a COOL "graphic"! (Unit: millisecond)
%s /path/to/process.log 6 7 -m -g

# Include all processes and print a COOL "graphic"! (Unit: tick)
%s /path/to/process.log -g
"""

class MyError(Exception):
    pass

class DuplicateNew(MyError):
    def __init__(self, pid):
	    args = "More than one 'N' for process %d." % pid
	    MyError.__init__(self, args)

class UnknownState(MyError):
    def __init__(self, state):
	    args = "Unknown state '%s' found." % state
	    MyError.__init__(self, args)

class BadTime(MyError):
    def __init__(self, time):
	    args = "The time '%d' is bad. It should >= previous line's time." % time
	    MyError.__init__(self, args)

class TaskHasExited(MyError):
    def __init__(self, state):
	    args = "The process has exited. Why it enter '%s' state again?" % state
	    MyError.__init__(self, args)

class BadFormat(MyError):
    def __init__(self):
	    args = "Bad log format"
	    MyError.__init__(self, args)

class RepeatState(MyError):
	def __init__(self, pid):
		args = "Previous state of process %d is identical with this line." % (pid)
		MyError.__init__(self, args)

class SameLine(MyError):
	def __init__(self):
		args = "It is a clone of previous line."
		MyError.__init__(self, args)

class NoNew(MyError):
	def __init__(self, pid, state):
		args = "The first state of process %d is '%s'. Why not 'N'?" % (pid, state)
		MyError.__init__(self, args)

class statistics:
	def __init__(self, pool, include, exclude):
		if include:
			self.pool = process_pool()
			for process in pool:
				if process.getpid() in include:
					self.pool.add(process)
		else:
			self.pool = copy.copy(pool)

		if exclude:
			for pid in exclude:
				if self.pool.get_process(pid):
					self.pool.remove(pid)
	
	def list_pid(self):
		l = []
		for process in self.pool:
			l.append(process.getpid())
		return l

	def average_turnaround(self):
		if len(self.pool) == 0:
			return 0
		sum = 0
		for process in self.pool:
			sum += process.turnaround_time()
		return float(sum) / len(self.pool)

	def average_waiting(self):
		if len(self.pool) == 0:
			return 0
		sum = 0
		for process in self.pool:
			sum += process.waiting_time()
		return float(sum) / len(self.pool)
	
	def begin_time(self):
		begin = 0xEFFFFF
		for p in self.pool:
			if p.begin_time() < begin:
				begin = p.begin_time()
		return begin

	def end_time(self):
		end = 0
		for p in self.pool:
			if p.end_time() > end:
				end = p.end_time()
		return end

	def throughput(self):
		return len(self.pool) * HZ / float(self.end_time() - self.begin_time())

	def print_graphic(self):
		begin = self.begin_time()
		end = self.end_time()

		print graph_title

		for i in range(begin, end+1):
			line = "%5d " % i
			for p in self.pool:
				state = p.get_state(i)
				if state & P_NEW:
					line += "-"
				elif state == P_READY or state == P_READY | P_WAITING:
					line += "|"
				elif state == P_RUNNING:
					line += "#"
				elif state == P_WAITING:
					line += ":"
				elif state & P_EXIT:
					line += "-"
				elif state == P_NULL:
					line += " "
				elif state & P_RUNNING:
					line += "+"
				else:
					assert False
				if p.get_state(i-1) != state and state != P_NULL:
					line += "%-3d" % p.getpid()
				else:
					line += "   "
			print line

class process_pool:
	def __init__(self):
		self.list = []
	
	def get_process(self, pid):
		for process in self.list:
			if process.getpid() == pid:
				return process
		return None

	def remove(self, pid):
		for process in self.list:
			if process.getpid() == pid:
				self.list.remove(process)

	def new(self, pid, time):
		p = self.get_process(pid)
		if p:
			if pid != 0:
				raise DuplicateNew(pid)
			else:
				p.states=[(P_NEW, time)]
		else:
			p = process(pid, time)
			self.list.append(p)
		return p

	def add(self, p):
		self.list.append(p)

	def __len__(self):
		return len(self.list)
	
	def __iter__(self):
		return iter(self.list)

class process:
	def __init__(self, pid, time):
		self.pid = pid
		self.states = [(P_NEW, time)]
	
	def getpid(self):
		return self.pid

	def change_state(self, state, time):
		last_state, last_time = self.states[-1]
		if state == P_NEW:
			raise DuplicateNew(pid)
		if time < last_time:
			raise BadTime(time)
		if last_state == P_EXIT:
			raise TaskHasExited(state)
		if last_state == state and self.pid != 0: # task 0 can have duplicate state
			raise RepeatState(self.pid)

		self.states.append((state, time))

	def get_state(self, time):
		rval = P_NULL
		combo = P_NULL
		if self.begin_time() <= time <= self.end_time():
			for state, s_time in self.states:
				if s_time < time:
					rval = state
				elif s_time == time:
					combo |= state
				else:
					break
			if combo:
				rval = combo
		return rval

	def turnaround_time(self):
		return self.states[-1][S_TIME] - self.states[0][S_TIME]

	def waiting_time(self):
		return self.state_last_time(P_READY)

	def cpu_time(self):
		return self.state_last_time(P_RUNNING)

	def io_time(self):
		return self.state_last_time(P_WAITING)

	def state_last_time(self, state):
		time = 0
		state_begin = 0
		for s,t in self.states:
			if s == state:
				state_begin = t
			elif state_begin != 0:
				assert state_begin <= t
				time += t - state_begin
				state_begin = 0
		return time


	def begin_time(self):
		return self.states[0][S_TIME]

	def end_time(self):
		return self.states[-1][S_TIME]
		
# Enter point
if len(sys.argv) < 2:
	print usage.replace("%s", sys.argv[0])
	sys.exit(0)

# parse arguments
include = []
exclude = []
unit_ms = False
graphic = False
ex_mark = False

try:
	for arg in sys.argv[2:]:
		if arg == '-m':
			unit_ms = True
			continue
		if arg == '-g':
			graphic = True
			continue
		if not ex_mark:
			if arg == '-x':
				ex_mark = True
			else:
				include.append(int(arg))
		else:
			exclude.append(int(arg))
except ValueError:
	print "Bad argument '%s'" % arg
	sys.exit(-1)

# parse log file and construct processes
processes = process_pool()

f = open(sys.argv[1], "r")

# Patch process 0's New & Run state
processes.new(0, 40).change_state(P_RUNNING, 40)

try:
	prev_time = 0
	prev_line = ""
	for lineno, line in enumerate(f):

		if line == prev_line:
			raise SameLine
		prev_line = line

		fields = line.split("\t")
		if len(fields) != 3:
			raise BadFormat

		pid = int(fields[0])
		s = fields[1].upper()

		time = int(fields[2])
		if time < prev_time:
			raise BadTime(time)
		prev_time = time

		p = processes.get_process(pid)

		state = P_NULL
		if s == 'N':
			processes.new(pid, time)
		elif s == 'J':
			state = P_READY
		elif s == 'R':
			state = P_RUNNING
		elif s == 'W':
			state = P_WAITING
		elif s == 'E':
			state = P_EXIT
		else:
			raise UnknownState(s)
		if state != P_NULL:
			if not p:
				raise NoNew(pid, s)
			p.change_state(state, time)
except MyError, err:
	print "Error at line %d: %s" % (lineno+1, err)
	sys.exit(0)

# Stats
stats = statistics(processes, include, exclude)
att = stats.average_turnaround()
awt = stats.average_waiting()
if unit_ms:
	unit = "ms"
	att *= 1000/HZ
	awt *= 1000/HZ
else:
	unit = "tick"
print "(Unit: %s)" % unit
print "Process   Turnaround   Waiting   CPU Burst   I/O Burst"
for pid in stats.list_pid():
	p = processes.get_process(pid)
	tt = p.turnaround_time()
	wt = p.waiting_time()
	cpu = p.cpu_time()
	io = p.io_time()

	if unit_ms:
		print "%7d   %10d   %7d   %9d   %9d" % (pid, tt*1000/HZ, wt*1000/HZ, cpu*1000/HZ, io*1000/HZ)
	else:
		print "%7d   %10d   %7d   %9d   %9d" % (pid, tt, wt, cpu, io)
print "Average:  %10.2f   %7.2f" % (att, awt)
print "Throughout: %.2f/s" % (stats.throughput())

if graphic:
	stats.print_graphic()

運(yùn)行這個(gè)文件:python2 stat_log.py process.log,得到實(shí)驗(yàn)結(jié)果。

哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)

?參考博客:

(112條消息) 操作系統(tǒng)實(shí)驗(yàn)四 進(jìn)程運(yùn)行軌跡的跟蹤與統(tǒng)計(jì)(哈工大李治軍)_Casten-Wang的博客-CSDN博客https://blog.csdn.net/leoabcd12/article/details/120107478文章來源地址http://www.zghlxwxcb.cn/news/detail-503044.html

到了這里,關(guān)于哈工大操作系統(tǒng)實(shí)驗(yàn)三(整理自用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一——HTTP代理服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)

    哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一——HTTP代理服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)

    1. 設(shè)計(jì)并實(shí)現(xiàn)一個(gè)基本 HTTP 代理服務(wù)器。 要求在指定端口接收來自客戶的 HTTP 請(qǐng)求并且根據(jù)其中的 URL 地址訪問該地址所指向的 HTTP 服務(wù)器(原服務(wù)器),接收 HTTP 服務(wù)器的響應(yīng)報(bào)文,并將響應(yīng)報(bào)文轉(zhuǎn)發(fā)給對(duì)應(yīng)的客戶進(jìn)行瀏覽。 2. 設(shè)計(jì)并實(shí)現(xiàn)一個(gè)支持 Cache 功能的 HTTP 代理服

    2024年02月22日
    瀏覽(30)
  • 哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一-HTTP代理服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)

    哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一-HTTP代理服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)

    當(dāng)客戶在瀏覽器中設(shè)置好Proxy Server后,你使用瀏覽器訪問所有WWW站點(diǎn)的請(qǐng)求都不會(huì)直接發(fā)給目的主機(jī),而是先發(fā)給代理服務(wù)器,代理服務(wù)器接受了客戶的請(qǐng)求以后,由代理服務(wù)器向目的主機(jī)發(fā)出請(qǐng)求,并接受目的主機(jī)的數(shù)據(jù),存于代理服務(wù)器的硬盤中,然后再由代理服務(wù)器將

    2023年04月24日
    瀏覽(50)
  • 哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)四——簡單網(wǎng)絡(luò)組建配置 Cisco Packet Tracer 使用指南

    哈工大計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)四——簡單網(wǎng)絡(luò)組建配置 Cisco Packet Tracer 使用指南

    做實(shí)驗(yàn)四時(shí),本來希望能夠借助實(shí)驗(yàn)指導(dǎo)書上的內(nèi)容速通,但嘗試了一個(gè)上午后發(fā)現(xiàn)遍地都是bug,于是便花了半天的時(shí)間認(rèn)真學(xué)習(xí)了一下其中的運(yùn)行機(jī)制,晚上又把所有的switch全都重寫了一遍,最后終于成功。這篇博客詳細(xì)介紹了該實(shí)驗(yàn)中使用Cisco Packet Tracer組建校園網(wǎng)的過程

    2024年02月09日
    瀏覽(58)
  • 計(jì)算理論期末2022哈工大

    一、請(qǐng)回答關(guān)于圖靈機(jī)的問題。(15 分) 確定圖靈機(jī)的形式化定義是什么? 不確定圖靈機(jī)和確定圖靈機(jī)的區(qū)別是什么? 二、請(qǐng)回答設(shè)計(jì)圖靈機(jī)相關(guān)的問題(畫出狀態(tài)轉(zhuǎn)移圖即可)。(15 分) 構(gòu)造確定圖靈機(jī)識(shí)別語言 L={0m1 n | m=0, n0}。 構(gòu)造確定圖靈機(jī)識(shí)別語言 L={0n1 n | n0}。 構(gòu)造

    2024年02月10日
    瀏覽(31)
  • 哈工大近世代數(shù)期末復(fù)習(xí)

    哈工大近世代數(shù)期末復(fù)習(xí)

    近世代數(shù)是抽象代數(shù)的一個(gè)分支,是計(jì)算機(jī)科學(xué)和人工智能大數(shù)據(jù)的基礎(chǔ).? 本文內(nèi)容有點(diǎn)長,大家可以通過index來跳轉(zhuǎn)到想要看的章節(jié),第十章的總結(jié)在我的主頁里下載 method1 有單位元 有逆元 運(yùn)算滿足結(jié)合律 method2: 運(yùn)算滿足結(jié)合律 運(yùn)算滿足左右消去律 定義:滿足交換律的群 應(yīng)

    2024年02月05日
    瀏覽(25)
  • 哈工大機(jī)器學(xué)習(xí)期末復(fù)習(xí)筆記(一)

    哈工大機(jī)器學(xué)習(xí)期末復(fù)習(xí)筆記(一)

    一、貝葉斯估計(jì) 當(dāng)我們需要對(duì)一個(gè)參數(shù)進(jìn)行估計(jì)時(shí),一種辦法是概率論與數(shù)理統(tǒng)計(jì)課程中已經(jīng)學(xué)過的極大似然估計(jì)(Maximum Likelihood Estimation,MLE)。例如,如果我們想估計(jì)扔硬幣正面朝上的概率p,可以扔N次,記錄正面朝上的次數(shù)M,再用M/N估計(jì)p。這種方法得到的參數(shù)估計(jì)是個(gè)

    2024年02月01日
    瀏覽(23)
  • 哈工大CSAPP程序人生大作業(yè)

    正在上傳…重新上傳取消 計(jì)算機(jī)系統(tǒng) 大作業(yè) 題 ????目 ? 程序人生 -Hello’s P2P? 專?????? 業(yè) ?? 計(jì)算機(jī)科學(xué)與技術(shù) ?????? 學(xué) ?? 號(hào) ??2021110991???????????? 班 ?? 級(jí) ?????2103101???????????? 學(xué)?????? 生 ??????? 安心 ????????? 指 導(dǎo) 教 師 ???

    2023年04月24日
    瀏覽(26)
  • 專業(yè)140+總410+哈爾濱工業(yè)大學(xué)803信號(hào)與系統(tǒng)和數(shù)字邏輯電路考研經(jīng)驗(yàn)哈工大電子信息(信息與通信工程-信通)

    專業(yè)140+總410+哈爾濱工業(yè)大學(xué)803信號(hào)與系統(tǒng)和數(shù)字邏輯電路考研經(jīng)驗(yàn)哈工大電子信息(信息與通信工程-信通)

    一年的努力付出終于有了收獲,今年專業(yè)課140+,總分410+順利上岸哈工大803電子信息(信息與通信-信通),回顧總結(jié)了自己這一年的復(fù)習(xí),有得有失,希望對(duì)大家復(fù)習(xí)有所幫助。 數(shù)學(xué) 時(shí)間安排:3月-7月:看基礎(chǔ)課程+《660題》 7-9月:強(qiáng)化課程+《880題》一刷和二刷 9-10月:往年

    2024年01月17日
    瀏覽(22)
  • 哈工大 2022春 模式識(shí)別與深度學(xué)習(xí) 期末試題

    雖然此課程未開卷考試,但往年題還是很有參考價(jià)值的,就像今年的題和2021年就有很多到相似的題。但考的知識(shí)點(diǎn)肯定比題多,考試前還是需要把PPT都過一遍的。 已知條件概率和先驗(yàn)概率,求基于最小錯(cuò)誤率的貝葉斯分類器 如果你有一個(gè)朋友在外地…(HMM PPT上的原題改很少

    2024年02月09日
    瀏覽(22)
  • 哈工大csapp-LAB3程序優(yōu)化

    實(shí)驗(yàn)報(bào)告 實(shí) 驗(yàn)(三) 題???? 目 ????? 優(yōu)化 ??????? ??????? 專?????? 業(yè) ??? 人工智能(未來技術(shù)) ??? 學(xué) ?? 號(hào) ???7203610716????????????? 班 ?? 級(jí) ???20WJ102??????????????? 學(xué)?????? 生 ??? 孫銘蔚 ??????????? 指 導(dǎo) 教 師 ??? 劉宏偉

    2023年04月24日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包