文档库 最新最全的文档下载
当前位置:文档库 › 兰州大学操作系统实验五详细答案

兰州大学操作系统实验五详细答案

兰州大学操作系统实验五详细答案
兰州大学操作系统实验五详细答案

实验五

实验名称:

进程管理

实验报告:

实验要求: cat /etc/group (查看组信息)

1.编写一个程序,打印进程的如下信息:进程标识符,父进程标识符,真实用户ID,有效

用户ID,真实用户组ID,有效用户组ID。并分析真实用户ID和有效用户ID的区别。

代码如下:

#include

#include

int main(){

printf("***********\n");

printf("This is the process\n");

printf(" pid=%d\n",getpid());

printf("ppid=%d\n",getppid());

printf(" uid=%d\n",getuid());

printf("euid=%d\n",geteuid());

printf(" gid=%d\n",getgid());

printf("egid=%d\n",getegid());

}

真实用户ID和有效用户ID的区别:

真实用户ID:这个ID就是我们登陆unix系统时的身份ID。

有效用户ID:定义了操作者的权限。有效用户ID是进程的属性,决定了该进程对文件的访问权限.

2.阅读如下程序:

/* process using time */

#include

#include

#include

#include

#include

void time_print(char *,clock_t);

int main(void)

{

clock_t start,end;

struct tms t_start,t_end;

start = times(&t_start);

system(“grep the /usr/doc/*/*> /dev/null2> /dev/null”); // > 将信息放到该文件null中end=times(&t_end); //0 1 2 标准输入标准输出错误输出time_ print(“elapsed”,end-start);

puts(“parent times”);

time _print(“\tuser CPU”,t_end.tms _utime);

time_ print(“\tsys CPU”,t_end.tms_stime);

//获得执行system()的子进程ID

puts(“child times”);

time_print(“\tuser CPU”,t_end.tms_cutime);

time_print(“\tsys CPU”,t_end.tms_cstime);

exit(EXIT_SUCCESS);

}

void time_print(char *str, clock_t time)

{

long tps = sysconf(_SC_CLK_TCK);/*函数sysconf()的作用为将时钟滴答数转化为

秒数,_SC_CLK_TCK 为定义每秒钟有多少个滴答的宏*/

printf(“%s: %6.2f secs\n”,str,(float)time/tps);

}

编译并运行,分析进程执行过程的时间消耗(总共消耗的时间和CPU消耗的时间),并解释执行结果。再编写一个计算密集型的程序替代grep,比较两次时间的花销。注释程序主要语句。

因为该程序计算量很小,故消耗的时间比较少,均为0.00secs 不奇怪。

而更改为计算密集型的之后就较容易观察出消耗时间的差异,如图所示。

3.阅读下列程序:

/* fork usage */

#include

#include

#include

int main(void)

{

pid_t child;

if((child=fork())==-1{

perror(“fork”);

exit(EXIT_FAILURE);

}else if(child==0){

puts(“in child”);

printf(“\tchild pid = %d\n”,getpid()); //取得目前进程的进程ID

printf(“\tchild ppid = %d\n”,getppid());//取得目前进程的父进程ID

exit(EXIT_SUCCESS);

}else{

puts(“in parent”);

printf(“\tparent pid = %d\n”,getpid());

printf(“\tparent ppid = %d\n”,getppid());

}

exit(EXIT_SUCCESS);

}

编译并多次运行,观察执行输出次序,说明次序相同(或不同)的原因;观察进程ID,分析进程ID的分配规律。总结fork()的使用方法。注释程序主要语句。

创建进程ID开始时一般随机分配,但若多次运行,或创建子进程时,会顺序分配内存。此外,当父进程结束时,子进程尚未结束,则子进程的父进程ID变为1,即init fork()的使用方法:

fork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,如果fork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。如果fork 失败则直接返回-1,失败原因存于errno中。

在父进程中用fork()创建子进程,通过返回值if语句判断来进行父子进程代码执行。

4.阅读下列程序:

/* usage of kill,signal,wait */

#include

#include

#include

#include

int flag;

void stop(); //该函数是自定义的一个single()触发的自定义函数

int main(void)

{

int pid1,pid2; //定义了两个进程号参数

signal(3,stop); //signal() 触发软中断

while((pid1=fork()) ==-1); //程序等待成功创建子进程事件的发生

if(pid1>0){

while((pid2=fork()) ==-1);

if(pid2>0){ //当前进程为父进程,父进程发出两个中断信号Kill子进程flag=1;

sleep(5);

kill(pid1,16);

kill(pid2,17);

wait(0); //等待子进程死信号

wait(0);

printf(“\n parent is killed\n”); //接收到子进程死信号后,杀死父进程

exit(EXIT_SUCCESS);

}else{ //当前进程为子进程,则发送子进程Kill信号,杀死该子进程2 flag=1;

signal(17,stop);

printf(“\n child2 is killed by parent\n”);

exit(EXIT_SUCCESS);

}

}else{ //当前进程为子进程,则发送子进程Kill信号,杀死该子进程1 flag=1;

signal(16,stop);

printf(“\n child1 is killed by parent\n”);

exit(EXIT_SUCCESS);

}

}

void stop(){ //自定义函数,供signal()调用

flag = 0;

}

编译并运行,等待或者按^C,分别观察执行结果并分析,注释程序主要语句。

flag有什么作用?通过实验说明。

每个进程(父进程,子进程)都有一个flag,起状态标志作用,flag=1时,表示进程在运行,flag=0,表示进程结束。

5.编写程序,要求父进程创建一个子进程,使父进程和子进程各自在屏幕上输出一些信息,

但父进程的信息总在子进程的信息之后出现。(分别通过一个程序和两个程序实现)

代码如下:

Ptest.c ---------------一个程序实现方案(fork())

#include

#include

#include

main()

{

while((p=fork())==-1); //创建子进程直至成功

if(p>0)

{

wait(0);

printf("***\n");

printf("The parent process!\n");

printf("***\n");

exit(0);

}

else{

printf("***\n");

printf("The child process!\n");

printf("***\n");

sleep(3);

exit(0);

}

}

/////////////////////////////////////////////////////////////////////////////////////

Ptest2.c ------------------两个程序实现方案(execl())

#include

#include

#include

int main(int argc,char *argv[])

{

int p,i;

while((p=fork())==-1); //创建子进程直至成功

if(p>0)

{

wait(0);

printf("***\n");

printf("The parent process!\n");

printf("***\n");

exit(0);

}

else{

printf("***\n");

printf("The child process!\n");

execl("/home/xingkong/ptest22",argv[1],(char*)0);

printf("***\n");

sleep(3);

exit(0);

}

}

#include

#include

int main(int argc,char *argv[])

{

int i;

printf("*****\nThis is two process\n*****\n");

for(i=0;i

{

printf("parameter %d is:%s\n",i,argv[i]);

}

return 0;

}

6.编写程序,要求父进程创建一个子进程,子进程执行shell命令find / -name hda* 的功能,

子进程结束时由父进程打印子进程结束的信息。执行中父进程改变子进程的优先级。

代码如下:

#include

#include

#include

#include

#include

#include

#include

main(){

pid_t pid;

int status;

pid=fork();

if(pid>0){

//在父进程中设置子进程优先级

setpriority(PRIO_PROCESS,pid,15);

//输出修改后的子进程的优先级

printf("the priority of son process is %d\n",getpriority(PRIO_PROCESS,pid));

}

//子进程执行代码

else{

execlp("find", "find", "/", "-name", "hda*", (char *)0);

exit(127);

}

/*使用waitpid()阻塞等待子进程结束,防止父进程过早的退出。子进程终止后,waitpid()返回

返回后,可以打印子进程已经终止的信息。*/

if ( (pid = waitpid(pid, &status, 0)) == -1) {

fprintf(stderr, "[parent] waitpid error: %s\n", strerror(errno));

exit(-1);

}

fprintf(stdout, "child[%d] terminated\n", pid);

exit(0);

}

7.编写程序,要求父进程创建一个子进程,子进程对一个50*50的字符数组赋值,由父进

程改变子进程的优先级,观察不同优先级进程使用CPU的时间。

代码如下:

#include

#include

#include

#include

#include

#include

void time_print(char *str,clock_t time){

long tps=sysconf(_SC_CLK_TCK);

printf("%s:%6.2f secs",str,(float)time/tps);

}

main(){

pid_t pid;

clock_t start,end;

struct tms t_start,t_end;

pid=fork();

start=times(&t_start);

if(pid>0){

//在父进程中设置子进程优先级

setpriority(PRIO_PROCESS,pid,20);

//输出修改后的子进程的优先级

printf("the priority of son process is%d",getpriority(PRIO_PROCESS,pid)); }

//子进程执行代码

else{

int i,j,shu[50][50];

for(i=0;i<50;i++)

for(j=0;j<50;j++)

shu[i][j]=i+j;

system("grep the /usr/*/*/* >/dev/null 2>/dev/null");

}

end=times(&t_end);

time_print("\nelapsed",end-start);

printf("\nparent time");

time_print("\tuser CPU",t_end.tms_utime);

time_print("\tsys CPU",t_end.tms_stime);

printf("\nchild time");

time_print("\tuser CPU",t_end.tms_cutime);

time_print("\tsys CPU",t_end.tms_cstime);

printf("\n");

exit(0);

}

8.编写一个程序,模拟实现一个简单的进程管理子系统,它由进程建立模块、进程撤销模

块、进程控制表组成。该子系统通过循环显示“please input new command”接收新进程,根据用户键入内容(命令)启动新进程,然后不等待新进程结束就显示“please input new command”接收新进程。建立和撤销进程时修改进程控制表。

9.查阅Linux系统中struct task_struct(有很多结构体类型的指针,至少写出三级指针)

的定义,说明每项成员的作用。(熟记该嵌套结构体)

Struct Task_struct{

*--------------------------------------→新的结构体定义{

*---------------------------------------→新的结构体定义

}

}

一级指针

每一个进程都有一个进程描述符,具体是task_struct结构体存储相关的信息. struct task_struct {

//这个是进程的运行时状态,-1代表不可运行,0代表可运行,>0代表已停止。 volatile long state;

/*

flags是进程当前的状态标志,具体的如:

0x00000002表示进程正在被创建;

0x00000004表示进程正准备退出;

0x00000040 表示此进程被fork出,但是并没有执行exec;

0x00000400表示此进程由于其他进程发送相关信号而被杀死。

*/

unsigned int flags;

//表示此进程的运行优先级

unsigned int rt_priority;

//list_head结构体

struct list_head tasks;

//mm_struct 结构体,该结构体记录了进程内存使用的相关情况

struct mm_struct *mm;

/* 接下来是进程的一些状态参数*/

int exit_state;

int exit_code, exit_signal;

//这个是进程号

pid_t pid;

//这个是进程组号

pid_t tgid;

//real_parent是该进程的“亲生父亲”,不管其是否被“寄养”。

struct task_struct *real_parent;

//parent是该进程现在的父进程,有可能是“继父”

struct task_struct *parent;

/*这里children指的是该进程孩子的链表,可以得到所有孩子的进程描述符,但是需使用list_for_each和list_entry,list_entry其实直接使用了container_of,详情请参考*/

struct list_head children;

//同理,sibling该进程兄弟的链表,也就是其父亲的所有孩子的链表。用法与children相似。

struct list_head sibling;

/*这个是主线程的进程描述符,也许你会奇怪,为什么线程用进程描述符表示,因为linux并没有单独实现线程的相关结构体,只是用一个进程来代替线程,然

后对其做一些特殊的处理。*/

struct task_struct *group_leader;

//这个是该进程所有线程的链表。

struct list_head thread_group;

//顾名思义,这个是该进程使用cpu时间的信息,utime是在用户态下执行的时间,stime是在内核态下执行的时间。

cputime_t utime, stime;

//下面的是启动的时间,只是时间基准不一样。

struct timespec start_time;

struct timespec real_start_time;

//comm是保存该进程名字的字符数组,长度最长为15,因为TASK_COMM_LEN为16。

char comm[TASK_COMM_LEN];

/* 文件系统信息计数*/

int link_count, total_link_count;

/*该进程在特定CPU下的状态*/

struct thread_struct thread;

/* 文件系统相关信息结构体*/

struct fs_struct *fs;

/* 打开的文件相关信息结构体*/

struct files_struct *files;

/* 信号相关信息的句柄*/

struct signal_struct *signal;

struct sighand_struct *sighand;

/*这些是松弛时间值,用来规定select()和poll()的超时时间,单位是纳秒nanoseconds */

unsigned long timer_slack_ns;

unsigned long default_timer_slack_ns;

};

二级结构体及对应的三级结构体(2.代表二级的,3.代表三级的)

2. struct mm_struct {//该结构体记录了进程内存使用的相关情况

int count;

pgd_t * pgd;//为指向进程页目录表的指针。

unsigned long context;//是进程上下文的地址

//分别为代码段、数据段的首地址和终止地址。

unsigned long start_code, end_code, start_data, end_data;

// start_stack是进程堆栈的首地址

unsigned long start_brk, brk, start_stack, start_mmap;

//分别为参数区、环境变量区的首地址和终止地址

unsigned long arg_start, arg_end, env_start, env_end;

unsigned long rss, total_vm, locked_vm;

unsigned long def_flags;

struct vm_area_struct * mmap;

struct vm_area_struct * mmap_avl;

struct semaphore mmap_sem;

};

3.struct vm_area_struct {

struct mm_struct * vm_mm;//指向进程的mm_struct结构体

//虚存空间的首地址和末地址后第一个字节的地址

unsigned long vm_start;

unsigned long vm_end;

//通过vm_next指针指向下一个vm_area_struct结构

struct vm_area_struct *vm_next;

//虚存区域的页面的保护特性

pgprot_t vm_page_prot;

unsigned long vm_flags;

// vm_flags指出了虚存区域的操作特性:

// VM_READ 虚存区域允许读取

// VM_WRITE 虚存区域允许写入

// VM_EXEC 虚存区域允许执行

// VM_SHARED 虚存区域允许多个进程共享

// VM_GROWSDOWN 虚存区域可以向下延伸

// VM_GROWSUP 虚存区域可以向上延伸

// VM_SHM 虚存区域是共享存储器的一部分

// VM_LOCKED 虚存区域可以加锁

// VM_STACK_FLAGS 虚存区域做为堆栈使用

/*vm_avl_hight(树高)、vm_avl_left(左子节点)、vm_avl_right (右子节点)三个成员来实现AVL树*/

short vm_avl_height;

struct vm_area_struct * vm_avl_left;

struct vm_area_struct * vm_avl_right;

/*vm_next_share和vm_prev_share,把有关vm_area_struct 结合成一个共享内存时使用的双向链表*/

struct vm_area_struct *vm_next_share;

struct vm_area_struct **vm_pprev_share;

struct vm_operations_struct * vm_ops;

unsigned long vm_pgoff;

struct file * vm_file;

unsigned long vm_raend;

void * vm_private_data;

};

2. struct list_head {

struct list_head *next, *prev;

};

在 Linux 内核链表中,需要用链表组织起来的数据通常会包含一个struct list_head 成员。这种通用的链表结构避免了为每个数据项类型定义自己的链表的麻烦。

两个指针分别指向双向链表的两个不同指向的指针

list_head的若干常用操作:

链表的插入删除合并操作:函数list_add(),list_add_tail(),list_del(),list_move(),list_move_tail(),list_empty(),list_splice();

2. struct fs_struct {

atomic_t count; 计数器

rwlock_t lock; 读写锁

int umask;

struct dentry * root, * pwd, * altroot;//根目录("/"),当前目录以及替换根目录

struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;

};

3. struct dentry {

atomic_t d_count; //目录项对象使用计数器,可以有未使用态,使用态和负状态

unsigned int d_flags; //目录项标志

struct inode * d_inode;// 与文件名关联的索引节点

struct dentry * d_parent;// 父目录的目录项对象

struct list_head d_hash; //散列表表项的指针

struct list_head d_lru; //未使用链表的指针

struct list_head d_child; //父目录中目录项对象的链表的指针

struct list_head d_subdirs; //对目录而言,表示子目录目录项对象的链表

struct list_head d_alias; //相关索引节点(别名)的链表

int d_mounted; //对于安装点而言,表示被安装文件系统根项

struct qstr d_name; //文件名

unsigned long d_time; /* used by d_revalidate */

struct dentry_operations *d_op; //目录项方法

struct super_block * d_sb;// 文件的超级块对象

vunsigned long d_vfs_flags;

void * d_fsdata; //与文件系统相关的数据

unsigned char d_iname [DNAME_INLINE_LEN]; //存放短文件名

};

3.struct vfsmount {

struct list_head mnt_hash; /* hash table list */

struct vfsmount *mnt_parent; /* parent filesystem */

struct dentry *mnt_mountpoint; /* dentry of this mount point */ struct dentry *mnt_root; /*dentry of root of this fs */

struct super_block *mnt_sb; /* superblock of this filesystem */ struct list_head mnt_mounts; /* list of children */

struct list_head mnt_child; /* list of children */

atomic_t mnt_count; /* usage count */

int mnt_flags; /* mount flags */

char*mnt_devname; /* device file name */

struct list_head mnt_list; /* list of descriptors */

struct list_head mnt_fslink; /* fs-specific expiry list */

struct namespace*mnt_namespace; /* associated namespace */ };

2. struct files_struct

{

atomic_t count; 使用该表的进程数

struct fdtable *fdt;

struct fdtable fdtab;

spinlock_t file_lock ____cacheline_aligned_in_smp;

int next_fd; 数值最小的最近关闭文件的文件描述符,下一个可用的文件描述符

struct embedded_fd_set close_on_exec_init; 执行exec时需要关闭的文件描述符初值集合

struct embedded_fd_set open_fds_init; 文件描述符的屏蔽字初值集合struct file * fd_array[NR_OPEN_DEFAULT]; 默认打开的fd队列

};

3.struct fdtable {

unsigned int max_fds;

struct file ** fd; //指向打开的文件描述符列表的指针,开始的时候指向fd_array,当超过max_fds时,重新分配地址

fd_set *close_on_exec;// 执行exec需要关闭的文件描述符位图(fork,exec即不被子进程继承的文件描述符)

fd_set *open_fds; // 打开的文件描述符位图

struct rcu_head rcu;

struct fdtable *next;

};

3.struct file {

union {

struct list_head fu_list; 文件对象链表指针linux/include/linux/list.h

struct rcu_head fu_rcuhead; RCU是Linux 2.6内核中新的锁机制

} f_u;

struct path f_path; 包含dentry和mnt两个成员,用于确定文件路径

const struct file_operations *f_op; 与该文件相关联的操作函数

atomic_t f_count; 文件的引用计数(有多少进程打开该文件)

unsigned int f_flags; 对应于open时指定的flag

mode_t f_mode; 读写模式:open的mod_t mode参数

off_t f_pos; 该文件在当前进程中的文件偏移量

struct fown_struct f_owner; 该结构的作用是通过信号进行I/O时间通知的数据。

unsigned int f_uid, f_gid; 文件所有者id,所有者组id

struct file_ra_state f_ra; 在linux/include/linux/fs.h中定义,文件预读相关

unsigned long f_version;

#ifdef CONFIG_SECURITY

void *f_security;

#endif

/* needed for tty driver, and maybe others */

void *private_data;

#ifdef CONFIG_EPOLL

/* Used by fs/eventpoll.c to link all the hooks to this file */

struct list_head f_ep_links;

spinlock_t f_ep_lock;

#endif /* #ifdef CONFIG_EPOLL */

struct address_space *f_mapping;

};

认识和体会:

1.对进程属性有所认知,通过学习,对子进程和父进程以及INIT的关系更加清晰。

2.进程的创建,fork()可以产生一个新的子进程,会复制父进程的数据代码,但进程ID是

不同的(及内存空间不同)。

3.用exec函数可以把当前进程替换为一个新进程,且新进程与原进程有相同的PID。

exec名下是由多个关联函数组成的一个完整系列,

头文件

extern char **environ;

原型:

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char * const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

带l 的exec函数:execl,execlp,execle,表示后边的参数以可变参数的形式给出且都以一个空指针结束。

带p 的exec函数:execlp,execvp,表示第一个参数path不用输入完整路径,只有给出命令名即可,它会在环境变量PATH当中查找命令。

不带l 的exec函数:execv,execvp表示命令所需的参数以char *arg[]形式给出且arg最后一个元素必须是NULL。

带 e 的exec函数:execle表示,将环境变量传递给需要替换的进程。

4.进程等待wait() waitpid().

5.还了解了信号处理signal()和优先权的获取与设置getpriority() setpriority() nice(),

以及进程正常结束exit().

操作系统实验报告_实验五

实验五:管道通信 实验内容: 1.阅读以下程序: #include #include #include main() { int filedes[2]; char buffer[80]; if(pipe(filedes)<0) //建立管道,filedes[0]为管道里的读取端,filedes[1]则为管道的写入端 //成功则返回零,否则返回-1,错误原因存于errno中 err_quit(“pipe error”); if(fork()>0){ char s[ ] = “hello!\n”; close(filedes[0]); //关闭filedes[0]文件 write(filedes[1],s,sizeof(s)); //s所指的内存写入到filedes[1]文件内 close(filedes[1]); //关闭filedes[0]文件 }else{ close(filedes[1]); read(filedes[0],buffer,80); //把filedes[0]文件传送80个字节到buffer缓冲区内 printf(“%s”,buffer); close(filedes[0]); } } 编译并运行程序,分析程序执行过程和结果,注释程序主要语句。

2.阅读以下程序: #include #include #include main() { char buffer[80]; int fd; unlink(FIFO); //删除FIFO文件 mkfifo(FIFO,0666); //FIFO是管道名,0666是权限 if(fork()>0){ char s[ ] = “hello!\n”;

操作系统课程设计答案

// tjty.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #define Bsize 3 #define Psize 20 struct pageInfor { int content;//页面号 int timer;//被访问标记 }; class PRA { public: PRA(void); int findSpace(void);//查找是否有空闲内存 int findExist(int curpage);//查找内存中是否有该页面 int findReplace(void);//查找应予置换的页面 void display(void);//显示 void FIFO(void);//FIFO算法 void LRU(void);//LRU算法 void Optimal(void);//OPTIMAL算法 void BlockClear(void);//BLOCK恢复 pageInfor * block;//物理块 pageInfor * page;//页面号串 private: }; PRA::PRA(void) { int QString[20]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1}; block = new pageInfor[Bsize]; for(int i=0; i

block[i].timer = 0; } page = new pageInfor[Psize]; for(i=0; i= block[pos].timer) pos = i;//找到应予置换页面,返回BLOCK中位置return pos; } void PRA::display(void) {

操作系统实验报告

操作系统教程 实 验 指 导 书 姓名: 学号: 班级:软124班 指导老师:郭玉华 2014年12月10日

实验一WINDOWS进程初识 1、实验目的 (1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。 (2)掌握WINDOWS API的使用方法。 (3)编写测试程序,理解用户态运行和核心态运行。 2、实验内容和步骤 (1)编写基本的Win32 Consol Application 步骤1:登录进入Windows,启动VC++ 6.0。 步骤2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 Consol Application”,然后在“Project name”处输入工程名,在“Location”处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”, 然后在“File”处输入C/C++源程序的文件名。 步骤4:将清单1-1所示的程序清单复制到新创建的C/C++源程序中。编译成可执行文件。 步骤5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的debug子目录,执行编译好的可执行程序: E:\课程\os课\os实验\程序\os11\debug>hello.exe 运行结果 (如果运行不成功,则可能的原因是什么?) : 有可能是因为DOS下路径的问题 (2)计算进程在核心态运行和用户态运行的时间 步骤1:按照(1)中的步骤创建一个新的“Win32 Consol Application”工程,然后将清单1-2中的程序拷贝过来,编译成可执行文件。 步骤2:在创建一个新的“Win32 Consol Application”工程,程序的参考程序如清单1-3所示,编译成可执行文件并执行。 步骤3:在“命令提示符”窗口中运行步骤1中生成的可执行文件,测试步骤2中可执行文件在核心态运行和用户态运行的时间。 E:\课程\os课\os实验\程序\os12\debug>time TEST.exe 步骤4:运行结果 (如果运行不成功,则可能的原因是什么?) : 因为程序是个死循环程序 步骤5:分别屏蔽While循环中的两个for循环,或调整两个for循环的次数,写出运行结果。 屏蔽i循环: 屏蔽j循环: _______________________________________________________________________________调整循环变量i的循环次数:

操作系统实验报告一

重庆大学 学生实验报告 实验课程名称操作系统原理 开课实验室DS1501 学院软件学院年级2013专业班软件工程2 班学生姓名胡其友学号20131802 开课时间2015至2016学年第一学期 总成绩 教师签名洪明坚 软件学院制

《操作系统原理》实验报告 开课实验室:年月日学院软件学院年级、专业、班2013级软件工 程2班 姓名胡其友成绩 课程名称操作系统原理 实验项目 名称 指导教师洪明坚 教师 评语教师签名:洪明坚年月日 1.实验目的: ?进入实验环境 –双击expenv/setvars.bat ?检出(checkout)EPOS的源代码 –svn checkout https://www.wendangku.net/doc/584830231.html,/svn/epos ?编译及运行 –cd epos/app –make run ?清除所有的临时文件 –make clean ?调试 –make debug ?在“Bochs Enhanced Debugger”中,输入“quit”退出调试 –调试指令,请看附录A 2.实验内容: ?编写系统调用“time_t time(time_t *loc)” –功能描述 ?返回从格林尼治时间1970年1月1日午夜起所经过的秒数。如果指针loc 非NULL,则返回值也被填到loc所指向的内存位置 –数据类型time_t其实就是long ?typedef long time_t; 3.实验步骤: ?Kernel space –K1、在machdep.c中,编写系统调用的实现函数“time_t sys_time()”,计算用户秒数。需要用到 ?变量g_startup_time,它记录了EPOS启动时,距离格林尼治时间1970年1午夜的秒数 ?变量g_timer_ticks

操作系统实验报告

《计算机操作系统》实验报告 教师: 学号: 姓名: 2012年3月6日 计算机学院

实验题目:请求页式存储管理(三) ----------------------------------------------------------------------------- 实验环境:VC6.0++ 实验目的:学生应独立地用高级语言编写几个常用的存储分配算法,并设计一个存储管理的模拟程序,对各种算法进行分析比较,评测其性能优劣,从而加深对这些算法的了解。实验内容: (1)编制和调试示例给出的请求页式存储管理程序,并使其投入运行。 (2)增加1~2种已学过的淘汰算法,计算它们的页面访问命中率。试用各种算法的命中率加以比较分析。(增加了FIFO) 操作过程: (1)产生随机数 (2)输入PageSize(页面大小1 /2/4/8 K) (pageno[i]=int(a[i]/1024)+1) (3)菜单选择

(4)OPT/ LRU/FIFO演示(pagesize=1K)

(5) 过程说明(PAGESIZE = 4K ) OPT :最佳置换算法(淘汰的页面是以后永不使用,或许是在最长时间内不再被访问的页面) //在Table 表中如果未找到,记录每个元素需要找的长度 //全部table 中元素找完长度,然后进行比较,找出最大的,进行淘汰 int max=0; int out; for(k=0;kmax){ max = table_time[k]; out = k; } }//找出最长时间,进行替换 table[out]=pageno[i]; page_out++;

操作系统实验报告心得体会

操作系统实验报告心得体会 每一次课程设计度让我学到了在平时课堂不可能学到的东西。所以我对每一次课程设计的机会都非常珍惜。不一定我的课程设计能够完成得有多么完美,但是我总是很投入的去研究去学习。所以在这两周的课设中,熬了2个通宵,生物钟也严重错乱了。但是每完成一个任务我都兴奋不已。一开始任务是任务,到后面任务就成了自己的作品了。总体而言我的课设算是达到了老师的基本要求。总结一下有以下体会。 1、网络真的很强大,用在学习上将是一个非常高效的助手。几乎所有的资料都能够在网上找到。从linux虚拟机的安装,到linux的各种基本命令操作,再到gtk的图形函数,最后到文件系统的详细解析。这些都能在网上找到。也因为这样,整个课程设计下来,我浏览的相关网页已经超过了100个(不完全统计)。当然网上的东西很乱很杂,自己要能够学会筛选。 不能决定对或错的,有个很简单的方法就是去尝试。就拿第二个实验来说,编译内核有很多项小操作,这些小操作错了一项就可能会导致编译的失败,而这又是非常要花时间的,我用的虚拟机,编译一次接近3小时。所以要非常的谨慎,尽量少出差错,节省时间。多找个几个参照资料,相互比较,

慢慢研究,最后才能事半功倍。 2、同学间的讨论,这是很重要的。老师毕竟比较忙。对于课程设计最大的讨论伴侣应该是同学了。能和学长学姐讨论当然再好不过了,没有这个机会的话,和自己班上同学讨论也是能够受益匪浅的。大家都在研究同样的问题,讨论起来,更能够把思路理清楚,相互帮助,可以大大提高效率。 3、敢于攻坚,越是难的问题,越是要有挑战的心理。这样就能够达到废寝忘食的境界。当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。 4、最好在做课设的过程中能够有记录的习惯,这样在写实验报告时能够比较完整的回忆起中间遇到的各种问题。比如当时我遇到我以前从未遇到的段错误的问题,让我都不知道从何下手。在经过大量的资料查阅之后,我对段错误有了一定的了解,并且能够用相应的办法来解决。 在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的 1)访问系统数据区,尤其是往系统保护的内存地址写数据,最常见就是给一个指针以0地址 2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域

操作系统原理实验-系统内存使用统计5

上海电力学院 计算机操作系统原理 实验报告 题目:动态链接库的建立与调用 院系:计算机科学与技术学院 专业年级:信息安全2010级 学生姓名:李鑫学号:20103277 同组姓名:无 2012年11 月28 日上海电力学院

实验报告 课程名称计算机操作系统原理实验项目线程的同步 姓名李鑫学号20103277 班级2010251班专业信息安全 同组人姓名无指导教师姓名徐曼实验日期2012/11/28 实验目的和要求: (l)了解Windows内存管理机制,理解页式存储管理技术。 (2)熟悉Windows内存管理基本数据结构。 (3)掌握Windows内存管理基本API的使用。 实验原理与内容 使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。 实验平台与要求 能正确使用系统函数GlobalMemoryStatus()和数据结构MEMORYSTATUS了解系统内存和虚拟空间使用情况,会使用VirtualAlloc()函数和VirtualFree()函数分配和释放虚拟存储空间。 操作系统:Windows 2000或Windows XP 实验平台:Visual Studio C++ 6.0 实验步骤与记录 1、启动安装好的Visual C++ 6.0。 2、选择File->New,新建Win32 Console Application程序, 由于内存分配、释放及系统存储 空间使用情况均是Microsoft Windows操作系统的系统调用,因此选择An application that support MFC。单击确定按钮,完成本次创建。 3、创建一个支持MFC的工程,单击完成。

操作系统实验报告

《操作系统》课程实验报告 专业:软件工程 班级:软件二班 学号: 2220111350 姓名:韩培培 序号: 14

目录: 实验一、进程的创建 实验二、进程控制 实验三、进程的管道通信 实验四、消息通信 实验五、进程调度 实验六、FIFO页面调度 实验七、LRU页面置换算法

实验一进程的创建 一.实验目的:进程的创建 二.实验内容:编写一段程序,使用系统调用 FORK( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“A”子进程分别显示字符“B”和“C”。试观察记录屏幕上的显示结果,并分析原因。 三.实验代码: #include <stdio.h> Main() { int p1,p2; While((p1=fork())==-1); If (p1==0) Putchar(ˊbˊ); else { While((p2=fork())==-1); If(p2==0) Putchar(ˊcˊ); else putchar(ˊaˊ); } } 四.实验运行结果

五.分析原因 程序首先调用Fork()函数创建一个子进程1.当创建进程不成功,循环创建进程,直至进程创建成功。如果Fork()返回值为0,表示当前进程是子进程1,显示字符B。如果Fork()返回值大于0,则表示当前进程是父进程,表示当前的程序代码是父进程所要执行的。父进程调用Fork()创建子进程2。当创建进程不成功时,循环创建进程直至成功。如果Fork()返回值为0,则表示当前进程是子进程2,显示字符C。如果Fork()返回值大于0,则表示当前进程 是父进程,输出字符A。

操作系统实验报告

操作系统实验报告 实验名称: 系统的引导 所在班级: 指导老师: 老师 实验日期: 2014年3 月29 日

一、实验目的 ◆熟悉hit-oslab实验环境; ◆建立对操作系统引导过程的深入认识; ◆掌握操作系统的基本开发过程; ◆能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱。 二、实验容 1. 阅读《Linux核完全注释》的第6章引导启动程序,对计算机和Linux 0.11的引导过程进行初步的了解。 2. 按照下面的要求改写0.11的引导程序bootsect.s。 3. 有兴趣同学可以做做进入保护模式前的设置程序setup.s。 4. 修改build.c,以便可以使用make BootImage命令 5. 改写bootsect.s主要完成如下功能: bootsect.s能在屏幕上打印一段提示信息XXX is booting...,其中XXX是你给自己的操作系统起的名字,例如LZJos、Sunix等。 6. 改写setup.s主要完成如下功能: bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s 向屏幕输出一行"Now we are in SETUP"。setup.s能获取至少一个基本的硬件参数(如存参数、显卡参数、硬盘参数等),将其存放在存的特定地址,并输出到屏幕上。setup.s不再加载Linux核,保持上述信息显示在屏幕上即可。 三、实验环境

本实验使用的系统是windows系统或者是Linux系统,需要的材料是osexp。 四、实验步骤 1. 修改bootsect.s中的提示信息及相关代码; 到osexp\Linux-0.11\boot目录下会看到图1所示的三个文件夹,使用UtraEdit 打开该文件。将文档中的98行的mov cx,#24修改为mov cx,#80。同时修改文档中的第246行为图2所示的情形。 图1图2 图3 2. 在目录linux-0.11\boot下,分别用命令as86 -0 -a -o bootsect.obootsect.s和 ld86 -0 -s -obootsectbootsect.o编译和bootsect.s,生成bootsect文件; 在\osexp目录下点击MinGW32.bat依此输入下面的命令: cd linux-0.11 cd boot as86 -0 -a -o bootsect.obootsect.s ld86 -0 -s -o bootsectbootsect.o

操作系统原理实验四

实验4 进程控制 1、实验目的 (1)通过对WindowsXP进行编程,来熟悉和了解系统。 (2)通过分析程序,来了解进程的创建、终止。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 (3)·CreateProcess()调用:创建一个进程。 (4)·ExitProcess()调用:终止一个进程。 4、实验编程 (1)编程一利用CreateProcess()函数创建一个子进程并且装入画图程序(mspaint.exe)。阅读该程序,完成实验任务。源程序如下: # include < stdio.h > # include < windows.h > int main(VOID) ﹛STARTUPINFO si; PROCESS INFORMA TION pi; ZeroMemory(&si,sizeof(si)); Si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, “c: \ WINDOWS\system32\ mspaint.exe”, NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) ﹛fprintf(stderr,”Creat Process Failed”); return—1; ﹜ WaitForSingleObject(pi.hProcess,INFINITE); Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜

操作系统实验报告

操作系统实验报告 集团企业公司编码:(LL3698-KKI1269-TM2483-LUI12689-ITT289-

实验二进程调度1.目的和要求 通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。 2.实验内容 阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。 编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。假设初始状态为:有n个进程处于就绪状态,有m个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。 程序要求如下: 1)输出系统中进程的调度次序; 2)计算CPU利用率。 3.实验环境 Windows操作系统、VC++6.0 C语言 4设计思想: (1)程序中进程可用PCB表示,其类型描述如下:

structPCB_type { intpid;//进程名 intstate;//进程状态 2——表示“执行”状态 1——表示“就绪”状态 0——表示“阻塞”状态 intcpu_time;//运行需要的CPU时间(需运行的时间片个数) } 用PCB来模拟进程; (2)设置两个队列,将处于“就绪”状态的进程PCB挂在队列ready中;将处于“阻塞”状态的进程PCB挂在队列blocked中。队列类型描述如下: structQueueNode{ structPCB_typePCB; StructQueueNode*next; } 并设全程量: structQueueNode*ready_head=NULL,//ready队列队首指针 *ready_tail=NULL,//ready队列队尾指 针

操作系统实验报告

操作系统实验报告 Document number:NOCG-YUNOO-BUYTT-UU986-1986UT

许昌学院 《操作系统》实验报告书学号: 姓名:闫金科 班级:14物联网工程 成绩: 2016年02月

实验一Linux的安装与配置 一、实验目的 1.熟悉Linux系统的基本概念,比如Linux发行版、宏内核、微内核等。 2.掌握Linux系统的安装和配置过程,初步掌握Linux系统的启动和退出方 法。 3.熟悉Linux系统的文件系统结构,了解Linux常用文件夹的作用。 二、实验内容 1.从网络上下载VMware软件和两个不同Linux发行版镜像文件。 2.安装VMware虚拟机软件。 3.在VMware中利用第一个镜像文件完成第一个Linux的安装,期间完成网络 信息、用户信息、文件系统和硬盘分区等配置。 4.在VMware中利用第二个镜像文件完成第二个Linux的安装,并通过LILO或 者GRUB解决两个操作系统选择启动的问题。 5.启动Linux系统,打开文件浏览器查看Linux系统的文件结构,并列举出 Linux常用目录的作用。 三、实验过程及结果 1、启动VMware,点击新建Linux虚拟机,如图所示: 2、点击下一步,选择经典型,点击下一步在选择客户机页面选择 Linux,版本选择RedHatEnterpriseLinux5,如图所示: 3、点击下一步创建虚拟机名称以及所要安装的位置,如图所示: 4、点击下一步,磁盘容量填一个合适大小,此处选择默认值大小 10GB,如图所示: 5、点击完成,点击编辑虚拟机设置,选择硬件选项中的CD-ROM (IDE...)选项,在右侧连接中选择“使用ISO镜像(I)”选项,点 击“浏览”,找到Linux的镜像文件,如图所示:

操作系统原理实验五

实验五线程的同步 1、实验目的 (1)进一步掌握Windows系统环境下线程的创建与撤销。 (2)熟悉Windows系统提供的线程同步API。 (3)使用Windows系统提供的线程同步API解决实际问题。 2、实验准备知识:相关API函数介绍 ①等待对象 等待对象(wait functions)函数包括等待一个对象(WaitForSingleObject ())和等待多个对象(WaitForMultipleObject())两个API函数。 1)等待一个对象 WaitForSingleObject()用于等待一个对象。它等待的对象可以为以下对象 之一。 ·Change ontification:变化通知。 ·Console input: 控制台输入。 ·Event:事件。 ·Job:作业。 ·Mutex:互斥信号量。 ·Process:进程。 ·Semaphore:计数信号量。 ·Thread:线程。 ·Waitable timer:定时器。 原型: DWORD WaitForSingleObject( HANDLE hHandle, // 对象句柄 DWORD dwMilliseconds // 等待时间 ); 参数说明: (1)hHandle:等待对象的对象句柄。该对象句柄必须为SYNCHRONIZE访问。 (2)dwMilliseconds:等待时间,单位为ms。若该值为0,函数在测试对象的状态后立即返回,若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒,如表2-1所示。 返回值: 如果成功返回,其返回值说明是何种事件导致函数返回。

Static HANDLE hHandlel = NULL; DWORD dRes; dRes = WaitForSingleObject(hHandlel,10); //等待对象的句柄为hHandlel,等待时间为10ms 2)等待对个对象 WaitForMultiple()bject()在指定时间内等待多个对象,它等待的对象与 WaitForSingleObject()相同。 原型: DWORD WaitForMultipleObjects( DWORD nCount, //句柄数组中的句柄数 CONST HANDLE * lpHandles, //指向对象句柄数组的指针 BOOL fWaitAll, //等待类型 DWORD dwMilliseconds //等待时间 ); 参数说明: (1)nCount:由指针 * lpHandles指定的句柄数组中的句柄数,最大数是MAXIMUM WAIT OBJECTS。 (2)* lpHandles:指向对象句柄数组的指针。 (3)fWaitAll:等待类型。若为TRUE,当由lpHandles数组指定的所有对象被唤醒时函数返回;若为FALSE,当由lpHandles数组指定的某一个 对象被唤醒时函数返回,且由返回值说明是由于哪个对象引起的函数 返回。 (4)dwMilliseconds:等待时间,单位为ms。若该值为0,函数测试对象的状态后立即返回;若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒。 返回值:、 如果成功返回,其返回值说明是何种事件导致函数返回。 各参数的描述如表2-2所示。

操作系统实验报告4

《操作系统》实验报告 实验序号: 4 实验项目名称:进程控制

Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜ 修改后: #include #include int main(VOID) { STARTUPINFO si; PROCESS_INFORMA TION pi; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, "c:\\WINDOWS\\system32\\mspaint.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) { fprintf(stderr,"Creat Process Failed"); return -1; } WaitForSingleObject(pi.hProcess,INFINITE); printf("child Complete"); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } 在“命令提示符”窗口运行CL命令产生可执行程序4-1.exe:C:\ >CL 4-1.cpp

实验任务:写出程序的运行结果。 4.正在运行的进程 (2)、编程二下面给出了一个使用进程和操作系统版本信息应用程序(文件名为4-5.cpp)。它利用进程信息查询的API函数GetProcessVersion()与GetVersionEx()的共同作用。确定运行进程的操作系统版本号。阅读该程序并完成实验任务。 #include #include

操作系统实验报告 (5)

实验名称:存储管理 学号班级姓名 1 实验目的: 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。 本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的技术特点,掌握请求页式存储管理的页面置换算法。 2 实验预备内容: (1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: ①50%的指令是顺序执行的; ②50%的指令是均匀分布在前地址部分; ③50%的指令是均匀分布在后地址部分。 具体的实施方法是: ①在 [0,319] 的指令之间随即选取一起点m; ②顺序执行一条指令,即执行地址为m+1的指令; ③在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m′; ④顺序执行一条指令,其地址为 m′+ 1; ⑤在后地址[m′+ 2,319]中随机选取一条指令并执行; ⑥重复上述步骤①-⑤,直到执行320次指令。 (2)将指令序列变换为页地址流 设:①页面大小为1k; ②用户内存容量为4页到32页; ③用户虚存容量为32k。 在用户虚存中,按每k存放10条指令排在虚存地址,即320条指令在虚存中的存放方式为: 第0条-第9条指令为第0页(对应虚存地址为[0,9]); 第10条-第19条指令为第一页(对应虚存地址为[10,19]); …… 第310条~第319条指令为第31页(对应虚地址为[310,319])。 按以上方式,用户指令可组成32页。 (3)计算并输出下述各种算法在不同内存容量下的命中率。 ①先进先出的算法(FIFO); ②最近最少使用算法(LRR); ③最佳淘汰算法(OPT)先淘汰最不常用的页地址; ④最少访问页面算法(LFR); ⑤最近最不经常使用算法(NUR)。 其中③和④为选择内容。

操作系统实验报告

操作系统实验报告 银行家算法 班级:计算机()班 姓名:李君益 学号:(号) 提交日期: 指导老师: 林穗 一、设计题目 加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用银行家算法,有效的防止和避免死锁的发生。 二、设计要求

内容: 编制银行家算法通用程序,并检测思考题中所给状态的安全性。 要求: (1)下列状态是否安全?(三个进程共享个同类资源) 进程已分配资源数最大需求数 (状态) (状态) (2)考虑下列系统状态 分配矩阵最大需求矩阵可用资源矩阵 问系统是否安全?若安全就给出所有的安全序列。若进程请求(),可否立即分配? 三、设计分析 一.关于操作系统的死锁 .死锁的产生 计算机系统中有许多独占资源,他们在任一时刻只能被一个进程使用,如磁带机,绘图仪等独占型外围设备,或进程表,临界区等软件资源。两个进程同时向一台打印机输出将导致一片混乱,两个进程同时进入临界区将导致数据库错误乃至程序崩溃。正因为这些原因,所有操作系统都具有授权一个进程独立访问某一辞源的能力。一个进程需要使用独占型资源必须通过以下的次序: ●申请资源 ●使用资源 ●归还资源 若申请施资源不可用,则申请进程进入等待状态。对于不同的独占资源,进程等待的方式是有差别的,如申请打印机资源、临界区资源时,申请失败将一位这阻塞申请进程;而申请打开文件文件资源时,申请失败将返回一个错误码,由申请进程等待一段时间之后重试。只得指出的是,不同的操作系统对于同一种资源采取的等待方式也是有差异的。 在许多应用中,一个进程需要独占访问多个资源,而操作系统允许多个进程并发执行共享系统资源时,此时可能会出现进程永远被阻塞的现象。这种现象称为“死锁”。 2.死锁的定义 一组进程处于死锁状态是指:如果在一个进程集合中的每个进程都在等待只能由该集合中的其他一个进程才能引发的时间,则称一组进程或系统此时发生了死锁。 .死锁的防止 .死锁产生的条件: ●互斥条件

操作系统原理实验2+岳青山+0907052247

《操作系统原理》实验报告 实验序号:2 实验项目名称: Windows 基本进程管理 1、实验目的 通过观察任务管理器,来观察各个进程的动态信息。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 ·任务管理器,了解用户计算机上正在运行的程序和进程的相关信息。 ·Windows环境中的编程。 相关内容参见本次实验参考资料部分。 4、基本实验 1)观察任务管理器 步骤一:进入WindowsXP。 步骤二:按Ctrl+Alt+Delete(或按Ctrl+Shift+Esc)键都可以调出任务管理器。 步骤三:单击“查看”→“选择列”选项,可以看到一些选项, 这里,可以查看每个进程的PID,CPU使用时间,内存的使用情况,当前的进程是系统的还是用户的,每个句柄的数量,每个进程的优先级,等等。 步骤四:单击“性能”标签,在所示的“性能”选项卡中可以看到CPU的使用情况、内存的使用情况。 2)通过命令观察进程情况、 步骤一:单击“开始”→“运行”选项,输入cmd“命令提示符”下。 步骤二:输入tasklist。 步骤三:继续输入tasklist/?来寻找帮助,里面有更详细的解释。 3)通过命令来关闭一个进程 步骤一:单击“开始”→“运行”选项,输入cmd“命令提示符”下。 步骤二:输入tasklist后回车执行。 步骤三:继续输入taskkill/PID 208/T 5、实验编程 进行一个简单的Windows的图形用户接口(GUI)编程。 步骤一:进入WindowsXP。 步骤二:进入Microsoft Visual Studio C++6.0。 步骤三:在菜单栏中单击“文件”→“新建”→“文件”→C++Source File,选择路径(如D:\1.cpp),并命名为1.cpp。 步骤四:将下面的程序源代码输入。 步骤五:单击Windows系统的“开始”→“运行”选项,输入cmd。

操作系统实验报告

实验二进程调度 1.目的和要求 通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。 2.实验内容 阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。 编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。假设初始状态为:有 n 个进程处于就绪状态,有m个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过 t 个时间片系统释放资源,唤醒处于阻塞队列队首的进程。 程序要求如下: 1)输出系统中进程的调度次序; 2)计算CPU利用率。 3.实验环境 Windows操作系统、VC++6.0 C语言

4 设计思想: (1)程序中进程可用PCB表示,其类型描述如下: struct PCB_type { int pid ;// 进程名 int state ;// 进程状态 2——表示“执行”状态 1——表示“就绪”状态 0——表示“阻塞”状态 int cpu_time ; //运行需要的CPU寸间(需运行的时间片 个数) } 用PCB来模拟进程; (2)设置两个队 列,将处于“就绪”状态的进程PCB挂在队列readyxx ;将处于“阻塞”状态的进程 PCB挂在队列blockedxx。 队列类型描述如下: struct QueueNode{

struct PCB_type PCB; Struct QueueNode *next; } 并设全程量: struct QueueNode *ready_head=NULL,//ready 队列队首指针 *ready_tail=NULL , //ready 队列队尾指针 *blocked_head=NULL,//blocked 队列队首指 针 *blocked_tail=NULL; //blocked 队列队尾指 针 (3)设计子程序: start_state(); 读入假设的数据,设置系统初始状态,即初始化就绪队列和 阻塞队列 dispath(); 模拟调度,当就绪队列的队首进程运行一个时间片后,放到就绪队列末尾,每次都是队首进程进行调度,一个进程运行结束 就从就绪队列中删除,当到 t 个时间片后,唤醒阻塞队列队首进程。

操作系统实验报告.

学生学号0121210680225 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称操作系统 开课学院计算机科学与技术学院 指导老师姓名刘军 学生姓名李安福 学生专业班级软件sy1201 2014 — 2015 学年第一学期

《操作系统》实验教学大纲 课程编号: 课程名称:操作系统/Operating System 实验总学时数:12学时 适应专业:计算机科学与技术、软件工程 承担实验室:计算机科学与技术学院实验中心 一、实验教学的目的和任务 通过实验掌握Linux系统下常用键盘命令、系统调用、SHELL编程、后台批处理和C程序开发调试手段等基本用法。 二、实验项目及学时分配 序号实验项目名称实验学时实验类型开出要求 01 Linux键盘命令和vi 2 设计必开 02 Linux下C编程 2 设计必开 03 SHELL编程和后台批处理 2 设计必开 04 Linux系统调用(time) 2 设计必开 05 Linux进程控制(fork) 4 设计必开 三、每项实验的内容和要求: 1、Linux键盘命令和vi 要求:掌握Linux系统键盘命令的使用方法。 内容:见教材p4, p9, p40, p49-53, p89, p100 2、Linux下的C编程 要求:掌握vi编辑器的使用方法;掌握Linux下C程序的源程序编辑方法;编译、连接和运行方法。 内容:设计、编辑、编译、连接以及运行一个C程序,其中包含键盘输入和屏幕输出语句。 3、SHELL编程和后台批处理 要求:掌握Linux系统的SHELL编程方法和后台批处理方法。 内容:(1) 将编译、连接以及运行上述C程序各步骤用SHELL程序批处理完成,前台运行。 (2) 将上面SHELLL程序后台运行。观察原C程序运行时输入输出情况。 (3) 修改调试上面SHELL程序和C程序,使得在后台批处理方式下,原键 盘输入内容可以键盘命令行位置参数方式交互式输入替代原键盘输入内容, 然后输出到屏幕。 4、Linux系统调用使用方法。

《操作系统原理》实验报告材料

《操作系统原理》 实验报告书 班级:__________ 学号:____________

姓名:_______________ 指导教师:______ 2013-2014 学年第二学期 实验名称:LINUX用户界面 ___________________ 实验时间:2014年4月2日第7周星期三 一、实验目的 1,熟悉Linux字符操作界面,熟练掌握常用Shell命令。 2,熟悉Linux文本编辑方法,学会编辑软件VI的使用。 3,了解Linux编译器gcc的功能,掌握基于Linux 平台的C程序的开发 二、实验预习(预备知识的问题及回答) 1.为什么在Linux系统中,诸如光盘、U盘等要先挂载而后才能使用?如何获得U盘的

设备名?装载点在文件系统中的位置是什么?

5Linux u Mou nt/dev/sdal/m nt/usb 6.什么是vi?其三种操作模式的含义是什么?给出三种工作模式间的转换图。 命令模式:vi启动后的默认模式,控制光标的移动,复制删除文字,进入输入模式和末行模式 输入模式:进行文字输入 末行模式:保存文件,退出VI 三、实验内容(包含实验所用命令或相关程序源代码) 1 . shell操作命令(给出每题所用的Shell命令或命令结果) (1 )创建名为stu1、stu2的2个用户,设置密码分别为student1 和student2 ,并将它们设为组group1中的成员。

#groupadd groupl #useradd stul -g groupl #su stul Spasswd stul 回车后敲入密码stude nt1 $exit #useradd stud2 -g groupl #su stu2 $passwd stu2 $exit (2)在每个用户的主目录下建立2个目录,分别命名为dirl和dir2。#su stul $cd~ $mkdir dirl $exit #su stu2 $ cd~ $mkdir dir2 $exit

相关文档