华中科技大学计算机学院操作系统课程设计报告[1]
华科操作系统实验

华科操作系统实验 Corporation standardization office #QS8QHH-HHGX8Q8-GNHHJ8课程实验报告课程名称:操作系统课程设计专业班级:学号:姓名:指导教师:报告日期:计算机科学与技术学院目录实验1:进程并发实验1.1 实验概述通过本次进程并发实验,让同学更加熟悉和理解Linux编程环境。
1.2 实验内容本次实验的内容主要分为两个任务:1.编写一个C程序,用read、write等系统调用实现文件拷贝功能。
命令形式:copy <源文件名> <目标文件名>2. 编写一个C程序,使用图形编程库 (QT/GTK)分窗口显示三个并发进程的运行(一个窗口实时显示当前系统时间,一个窗口循环显示0到9,一个窗口做1到1000的累加求和,刷新周期均为1秒)。
1.3 实验设计任务1:实验1的第一个阶段需要实现一个简单的C语言程序,首先需要有一个复制的源文件,同时需要创建一个存放复制内容的复制文件,文件复制传输的中间站可以设置一个缓冲数组,此次试验设计了一个大小为10个字节的数组。
打开复制源文件,返回一个INT标识,使用readbuf()函数,每次读取10个字节的内容,将内容存放到缓冲区数组,使用writebuf()函数将缓冲区的10个字节写到复制文件中,重复上述过程直到将整个复制过程完成。
任务2:实验的第二个阶段是实现进程的同步,实现的工具是QT。
主要实现3个进程的同步,3个进程分别为:实时显示系统时间、循环显示0-9、显示1-1000的累加和。
以上程序的刷新时间设置为1秒钟。
使用的是c++编程语言。
为了实现3个进程。
需要为这3个进程分别创建3个不同的类,这3个不用的类具有不同的成员函数,使用成员函数来实现进程的所代表的具体细节。
为了实现进程的结果能实时更新,需要调用connect()函数,该函数的功能是每当其中的timer每次发生变化时,就回调用该类的成员函数,也就是进程的具体实现,从而实时显示进程的细节内容。
操作系统实验报告--华科

实验一哲学家就餐问题一、实验目的1、熟练使用VC++6.0编译环境,调试并正确运行程序。
2、理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。
3、理解源程序中产生和防止死锁的算法,及相关窗口操作。
4、熟悉哲学家就餐问题流程。
5、在VC++6.0环境下编译哲学家就餐问题演示程序,考虑其他解决死锁方法.二、实验原理1、问题描述有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。
每个哲学家的行为是思考,感到饥饿,然后吃通心粉。
为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
2、分配方式方式一(不会进入死锁)仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子(所有线程需要的资源)进行下一步的吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。
方式二(会进入死锁)当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就有可能产生死锁了。
3、程序运行说明程序运行过程中会弹出一个MessageBox提示操作者操作:1)第一个对话框用于选择运行模式a.选择yes 表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。
b.选择no 表示运行产生死锁的方式会弹出第二个对话框。
2)第二个对话框用于选择运行时,线程运行的时间a. 选择res 线程时间比较短,很快就可以死锁b.选择no 线程时间跟选择yes 时候的时间差不多,产生死锁的时间稍微长一点。
三、实验过程及分析1、伪代码:1) 不发生死锁的方式(要么一下占用两支筷子,要么不占用)var mutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick); //先改变左手筷子信号量p(mutexrightchopstick); //马上改变右手筷子信号量GetResource(leftchopstick,rightchopstick);eating;v(mutexleftchopstick);v(mutexrightchopstick);end2) 发生死锁的方式(一旦可以占用筷子,就马上占用)var mutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick); //改变左手筷子信号量GetResource(leftchopstick); //获取左手筷子p(mutexrightchopstick); //改变右手筷子信号量GetResource(rightchopstick); //获取右手筷子eating;v(mutexleftchopstick);v(mutexrightchopstick);end2、代码分析:1)不发生死锁的方式:先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件。
《操作系统》课程设计报告

长江大学操作系统课程设计报告系(院):计算机科学学院专业班级:软工******姓名: ******* ***学号: 2013*****指导教师: *** **设计时间: 2015.12.27 - 2016.1.5设计地点: 4教5楼机房目录一、基本要求 (3)二、课程设计内容 (3)三、运行环境 (3)四、算法原理 (3)4.1银行家算法原理 (3)4.2页面置换算法原理 (3)4.3电梯调度算法原理 (4)五、程序结构 (4)5.1银行家算法结构 (4)5.2页面置换算法结构 (5)5.3电梯调度算法结构 (6)六、核心代码 (7)6.1银行家算法核心代码 (7)6.2页面置换算法核心代码 (13)6.3电梯调度算法核心代码 (17)七、运行结果截图 (20)7.1银行家算法截图 (20)7.2页面置换算法截图 (21)7.3电梯调度算法截图 (22)八、总结 (23)一、基本要求1.熟悉操作系统原理知识,理解各类管理算法。
2.能根据具体问题的数据特点,选用适当的数据结构,实现数据的组织和管理。
3.进一步巩固程序设计与数据结构的实践技能。
二、课程设计内容1.银行家算法模拟;2.页面置换算法模拟(OPT,FIFO,LRU);3.电梯调度算法(磁盘调度)模拟。
三、运行环境编程语言:C++,编程软件Microsoft Visual C++6.0,操作系统:Windows7。
四、算法原理4.1银行家算法原理银行家算法:系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。
如果资源分配不得到就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。
把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。
当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。
”资源需求总量”表示进程在整个执行过程中总共要申请的资源量。
华科操作系统实验

课程实验报告课程名称:操作系统课程设计专业班级:学号:姓名:指导教师:报告日期:计算机科学与技术学院目录实验1:进程并发实验 (1)实验概述 (1)实验内容 (1)实验设计 (1)实验过程 (2)实验结果 (6)实验小结 (7)实验2:添加系统功能调用 (8)实验概述 (8)实验内容 (8)阶段1 添加源代码 (8)阶段2 连接新的系统功能调用 (9)阶段3 重建内核 (10)阶段4 修改grub文件 (13)实验小结 (14)实验3:添加设备驱动程序 (15)实验概述 (15)实验内容 (15)阶段1 编写设备驱动程序 (15)阶段2 编译设备驱动模块 (16)阶段3 加载设备驱动模块 (17)阶段4 生成设备文件 (18)阶段5 编写应用程序测试 (18)实验小结 (19)实验总结 (20)实验1:进程并发实验实验概述通过本次进程并发实验,让同学更加熟悉和理解Linux编程环境。
实验内容本次实验的内容主要分为两个任务:1.编写一个C程序,用read、write等系统调用实现文件拷贝功能。
命令形式:copy <源文件名> <目标文件名>2.编写一个C程序,使用图形编程库 (QT/GTK)分窗口显示三个并发进程的运行(一个窗口实时显示当前系统时间,一个窗口循环显示0到9,一个窗口做1到1000的累加求和,刷新周期均为1秒)。
实验设计任务1:实验1的第一个阶段需要实现一个简单的C语言程序,首先需要有一个复制的源文件,同时需要创建一个存放复制内容的复制文件,文件复制传输的中间站可以设置一个缓冲数组,此次试验设计了一个大小为10个字节的数组。
打开复制源文件,返回一个INT标识,使用readbuf()函数,每次读取10个字节的内容,将内容存放到缓冲区数组,使用writebuf()函数将缓冲区的10个字节写到复制文件中,重复上述过程直到将整个复制过程完成。
任务2:实验的第二个阶段是实现进程的同步,实现的工具是QT。
华科操作系统课程设计

华科操作系统课程设计一、教学目标本课程的教学目标分为知识目标、技能目标和情感态度价值观目标。
知识目标:学生需要掌握操作系统的基本概念、原理和关键技术,包括进程管理、内存管理、文件系统、输入/输出系统等。
技能目标:学生能够运用操作系统的基本原理和关键技术,分析和解决实际问题。
通过实验和项目,培养学生的动手能力和创新能力。
情感态度价值观目标:培养学生对操作系统的兴趣和热情,提高学生的问题意识和团队协作精神。
二、教学内容本课程的教学内容主要包括操作系统的基本概念、原理和关键技术。
1.操作系统概述:操作系统的定义、功能、分类和发展历程。
2.进程管理:进程的概念、进程控制块、进程调度、同步与互斥、死锁。
3.内存管理:内存分配与回收策略、内存保护、虚拟内存、页面置换算法。
4.文件系统:文件和目录的概念、文件系统的结构、文件访问控制、磁盘空间分配策略。
5.输入/输出系统:输入/输出设备管理、中断处理、直接存储器访问(DMA)、设备驱动程序。
三、教学方法本课程采用多种教学方法,包括讲授法、讨论法、案例分析法和实验法。
1.讲授法:用于传授基本概念和原理,引导学生掌握操作系统的核心知识。
2.讨论法:通过小组讨论,培养学生的思考能力和团队协作精神。
3.案例分析法:分析实际案例,让学生了解操作系统在实际应用中的工作原理和解决问题的方式。
4.实验法:动手实践,培养学生的实际操作能力和创新能力。
四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备。
1.教材:选用国内知名出版社出版的操作系统教材,如《操作系统原理与实践》。
2.参考书:提供相关领域的经典著作和最新研究成果,供学生拓展阅读。
3.多媒体资料:制作课件、视频等资料,辅助教学,提高学生的学习兴趣。
4.实验设备:配置相应的实验设备,如计算机、网络设备等,为学生提供实践操作的机会。
五、教学评估本课程的评估方式包括平时表现、作业、考试等。
1.平时表现:评估学生的课堂参与度、提问回答、小组讨论等,以考查学生的学习态度和思考能力。
操作系统课程设计实验报告(附思考题答案)

操作系统课程设计实验报告(附思考题答案)课程设计(综合实验)报告( 2015 -- 2016 年度第 1 学期)名称:操作系统综合实验题目:oslab综合实验院系:计算机系班级:学号:学生姓名:指导教师:设计周数:分散进行成绩:日期:2015 年10 月29 日一、综合实验的目的与要求1. 理解和掌握操作系统的基本概念、基本组成与工作原理;2. 理解和掌握操作系统中主要功能模块的工作原理及其实现算法;3. 掌握软件模块设计技能;熟悉并能较好地利用软件开发环境独立编程、调试和分析程序运行情况,逐渐形成创新思维和从事系统软件的研究和开发能力。
二、实验正文实验1:实验环境的使用1.1实验目的:1.熟悉操作系统集成实验环境OS Lab 的基本使用方法。
2.练习编译、调试EOS 操作系统内核以及EOS 应用程序。
1.2实验内容:1.启动OS Lab2.学习OS Lab 的基本用法● 新建 Windows 控制台应用程序项目(1)在“文件”菜单中选择“新建”,然后单击“项目”。
(2)在“新建项目”对话框中,选择项目模板“控制台应用程序(c)”。
(3)在“名称”中输入新项目使用的文件夹名称“oslab ”。
(4)在“位置”中输入新项目保存在磁盘上的位置“C:\test ”。
(5)点击“确定”按钮。
● 生成、执行项目●3.EOS 内核项目的生成和调试● 新建 EOS 内核项目并按F7生成项目● 调试项目● 查看软盘镜像文件中的内容、EOS SDK (Software Development Kit )文件夹4.EOS 应用程序项目的生成和调试● 新建 EOS 应用程序项目● 修改 EOS 应用程序项目名称使用断点中断执行查看变量的值5.退出OS Lab6.保存EOS内核项目1.3思考与练习●在实验1中,生成EOS SDK文件夹的目的和作用是什么?答:SDK文件夹中提供了开发EOS应用程序需要的所有文件。
debug文件夹是在使用debug配置生成项目时生成的,其中存放了调试版本的EOS二进制文件。
华科操作系统实验报告

华科操作系统实验报告一、实验目的操作系统是计算机系统的核心组成部分,对于理解计算机的工作原理和提高计算机应用能力具有重要意义。
本次华科操作系统实验的主要目的是通过实际操作和实践,深入理解操作系统的基本概念、原理和功能,掌握操作系统的核心技术和应用方法,提高我们的实践能力和问题解决能力。
二、实验环境本次实验使用的操作系统为Windows 10 和Linux(Ubuntu 2004),开发工具包括 Visual Studio Code、GCC 编译器等。
实验硬件环境为个人计算机,配置为英特尔酷睿 i7 处理器、16GB 内存、512GB 固态硬盘。
三、实验内容1、进程管理进程创建与销毁进程调度算法模拟进程同步与互斥2、内存管理内存分配与回收算法实现虚拟内存管理3、文件系统文件操作与管理文件系统的实现与优化4、设备管理设备驱动程序编写设备分配与回收四、实验步骤及结果1、进程管理实验进程创建与销毁首先,使用 C 语言编写程序,通过系统调用创建新的进程。
在程序中,使用 fork()函数创建子进程,并在子进程和父进程中分别输出不同的信息,以验证进程的创建和执行。
实验结果表明,子进程和父进程能够独立运行,并输出相应的信息。
进程调度算法模拟实现了先来先服务(FCFS)、短作业优先(SJF)和时间片轮转(RR)三种进程调度算法。
通过模拟多个进程的到达时间、服务时间和优先级等参数,计算不同调度算法下的平均周转时间和平均等待时间。
实验结果显示,SJF 算法在平均周转时间和平均等待时间方面表现较好,而 RR 算法能够提供较好的响应时间和公平性。
进程同步与互斥使用信号量和互斥锁实现了进程的同步与互斥。
编写了生产者消费者问题的程序,通过信号量控制生产者和消费者对缓冲区的访问,避免了数据竞争和不一致的情况。
实验结果表明,信号量和互斥锁能够有效地实现进程间的同步与互斥,保证程序的正确性。
2、内存管理实验内存分配与回收算法实现实现了首次适应(First Fit)、最佳适应(Best Fit)和最坏适应(Worst Fit)三种内存分配算法。
操作系统课程设计报告

操作系统课程设计报告1. 引言操作系统是计算机系统中最核心的软件之一,它负责管理和优化计算机资源的分配和调度,为用户和应用程序提供一个可靠、高效的执行环境。
在操作系统课程设计中,我们通过设计一个简单的操作系统,深入理解操作系统的原理和功能,提升对操作系统的理解和实践能力。
本报告将详细介绍我们小组在操作系统课程设计过程中所完成的工作和实现的目标。
2. 设计目标在本次操作系统课程设计中,我们的设计目标包括:•实现一个基本的中断处理、进程调度和内存管理机制;•设计一个简单的文件系统;•确保操作系统的稳定性和可靠性;•实现用户命令解析和执行功能。
3. 系统架构我们的操作系统设计采用了经典的分层结构,主要由硬件抽象层、内核和用户接口层组成。
1.硬件抽象层:负责与硬件进行交互,提供基本的底层硬件接口,如处理器管理、中断处理、设备控制等。
2.内核:实现操作系统的核心功能,包括进程管理、内存管理、文件系统管理等。
这一层是操作系统的核心,负责管理和调度系统资源。
3.用户接口层:为用户提供简单友好的界面,解析用户输入的命令并调用内核功能进行处理。
用户可以通过命令行或图形界面与操作系统进行交互。
4. 功能实现4.1 中断处理中断是操作系统与外部设备通信的重要机制,我们的操作系统设计中实现了基本的中断处理功能。
通过在硬件抽象层中捕获和处理硬件的中断信号,内核可以对中断进行相应的处理,保证系统的响应能力和稳定性。
4.2 进程调度进程调度是操作系统中的重要任务之一,它决定了系统如何分配和调度上下文切换。
我们的操作系统设计中实现了一个简单的进程调度算法,通过时间片轮转算法和优先级调度算法来管理多个进程的执行顺序,以提高系统的吞吐量和响应性能。
4.3 内存管理内存管理是操作系统中必不可少的功能,它负责对系统内存的分配和回收。
我们的操作系统设计中实现了基本的内存管理功能,包括内存分区、内存空闲管理和地址映射等。
通过合理的内存管理,可以提高系统的内存利用率和性能。
操作系统课程设计报告

实践课设计报告课程名称操作系统课程设计模拟设计内存管理中的地址题目转换(动态分区、页式十进制)学院班级学号姓名指导教师年月日课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 模拟设计内存管理中的地址转换(动态分区、页式十进制)初始条件:1.预备内容:阅读操作系统的内存管理章节内容,理解动态分区、页式、段式和段页式存储管理的思想及相应的分配主存的过程。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.下列内部存储器管理中地址转换,在完成指定存储管理技术中的地址转换基础上还可以选择其它内部存储器管理中的地址转换进行模拟设计并实现:⑴动态分区方案,用最先适用算法对作业实施内存分配,然后把作业地址空间的某一逻辑地址转换成相应的物理地址。
能够处理以下的情形:输入某一逻辑地址,程序能判断地址的合法性,如果合法,计算并输出相应的物理地址。
如果不能计算出相应的物理地址,说明原因。
⑵页式存储管理中逻辑地址到物理地址的转换(十进制)。
能够处理以下的情形:输入某一十进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十进制表示。
⑶页式存储管理中逻辑地址到物理地址的转换(八进制)。
能够处理以下的情形:输入某一八进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用八进制表示。
⑷页式存储管理中逻辑地址到物理地址的转换(十六进制)。
能够处理以下的情形:输入某一十六进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十六进制表示。
⑸段式存储管理中逻辑地址到物理地址的转换。
能够处理以下的情形:指定内存的大小,进程的个数,每个进程的段数及段大小;能检查地址的合法性,如果合法进行转换,否则显示地址非法的原因。
⑹段页式存储管理中逻辑地址到物理地址的转换。
计算机操作系统课设操作系统课程设计报告

课程实验报告题目:操作系统原理专业班级:信息安全1302 班学号:姓名:指导教师:报告日期:2016 年2 月29 日计算机科学与技术学院目录1. 初探Linux 编程环境 (1)1.1. 实验目的 (1)1.2. 实验内容 (1)1.2.1. 实验一 (1)1.2.2. 实验二 (1)1.3. 实验设计 (1)1.3.1. 实验一 (1)1.3.2. 实验二 (2)1.4. 实验环境 (3)1.5. 实验步骤 (3)1.5.1. 实验一 (3)1.5.2. 实验二 (3)1.6. 调试记录 (4)1.6.1. 实验一 (4)1.6.2. 实验二 (4)1.7. 实验结果 (5)1.7.1. 实验一 (5)1.7.2. 实验二 (6)2. 通过编译内核的方式为Linux 增加系统调用 (8)2.1. 实验目的 (8)2.2. 实验内容 (8)2.3. 实验设计 (8)2.4. 实验环境 (8)2.5. 实验步骤 (8)2.6. 调试记录 (10)2.7. 实验结果 (11)3. 编写设备驱动程序 (13)3.1. 实验目的 (13)3.2. 实验内容 (13)3.3. 实验设计 (13)3.4. 实验环境 (14)3.5. 实验步骤 (14)3.6. 调试记录 (15)3.7. 实验结果 (15)4. 实现系统监控程序 (17)4.1. 实验目的 (17)4.2. 实验内容 (17)4.3. 实验设计 (18)4.4. 实验环境 (22)4.5. 实验步骤 (22)4.6. 调试记录 (22)4.7. 实验结果 (23)5. 设计模拟文件系统 (28)5.1. 实验目的 (28)5.2. 实验内容 (28)5.3. 实验设计 (28)5.4. 实验环境 (33)5.5. 实验步骤 (34)5.6. 调试记录 (34)5.7. 实验结果 (34)6. 附注:程序清单 (39)6.1. 文件拷贝程序 (39)6.2. 多进程多窗口实验 (40)6.3. 编译内核添加系统调用 (41)6.4. 编写模块 (43)6.5. 任务监视器 (49)6.6. 模拟文件系统 (64)1. 初探Linux 编程环境1.1. 实验目的掌握Linux 操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux 下的编程环境,了解在Linux 如何进行多线程编程以及图形编程。
计算机操作系统课程设计报告

操作系统课程设计课程设计目的本设计的目的是实现操作系统和相关系统软件的设计,其中涉及进程编程、I/O操作、存储管理、文件系统等操作系统概念。
课程设计要求(1)对进行认真分析,列出实验具体步骤,写出符合题目要求的程序清单,准备出调试程序使用的数据。
(2)以完整的作业包的形式提交原始代码、设计文档和可运行程序。
提交的光盘应当包括:设计题目,程序清单,运行结果分析,所选取的算法及其优缺点,以及通过上机取得了哪些经验。
程序清单要求格式规范,注意加注释(包含关键字、方法、变量等),在每个模块前加注释,注释不得少于20%。
课程设计要求同时上交打印文档,设计报告包括设计题目,算法分析,关键代码及其数据结构说明,运行结果分析以及上机实践的经验总结。
设计一:设计任务:模拟Linux文件系统在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟Linux文件系统。
1.在现有机器硬盘上开辟100M的硬盘空间,作为设定的硬盘空间。
2.编写一管理程序simdisk对此空间进行管理,以模拟Linux文件系统,要求:(1)盘块大小1k(2)空闲盘块的管理:Linux位图法(3)结构:超级块, i结点区, 根目录区3.该simdisk管理程序的功能要求如下:(1)info: 显示整个系统信息(参考Linux文件系统的系统信息),文件可以根据用户进行读写保护。
目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。
(2)cd …: 改变目录:改变当前工作目录,目录不存在时给出出错信息。
(3)dir …: 显示目录:显示指定目录下或当前目录下的信息,包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)。
(4)md …: 创建目录:在指定路径或当前路径下创建指定目录。
重名时给出错信息。
(5)rd …: 删除目录:删除指定目录下所有文件和子目录。
要删目录不空时,要给出提示是否要删除。
华科操作系统实验报告

课程实验报告课程名称:操作系统原理专业班级:学号:姓名:指导教师:报告日期:计算机科学与技术学院目录目录 (2)实验一:线程的同步 (3)一、实验目的 (3)二、实验内容 (3)三、实验心得 (6)实验二:誊抄实验的进程实现 (7)一、实验目的 (7)二、实验内容 (7)三、实验心得 (10)实验三:Linux文件目录操作 (12)一、实验目的 (12)二、实验内容 (12)三、实验心得 (14)实验一:线程的同步一、实验目的1、掌握Linux系统用户界面中键盘命令的使用。
2、学会一种Linux下的编程环境。
3、掌握Linux下进(线)程的概念。
4、了解Linux进程同步与通信的主要机制,并通过信号灯操作实现进程间的同步与互斥。
二、实验内容1、程序要求两个线程,共享公共变量a线程1负责计算(+1)线程2负责打印2、运行环境软件配置(含操作系统版本):ubuntu - 14.10硬件:PC3、源程序源程序:#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <sys/types.h>#include <sys/sem.h>#include <sys/ipc.h>int semid;int a=0;typedef union senum{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *_buf;}SEM_CTL_UN;void P(int semid,int index){struct sembuf sem; sem.sem_num = index; sem.sem_op = -1;//P sem.sem_flg = 0;//biaoji semop(semid,&sem,1); }void V(int semid,int index) {struct sembuf sem; sem.sem_num = index; sem.sem_op = 1; sem.sem_flg = 0; semop(semid,&sem,1); }void* thread1(void *arg) {int i=0;for(i;i<8;i++){P(semid,0);printf("add:\n");a=a+1;printf("a=%d\n",a);V(semid,1);}}void* thread2(void *arg) {int i=0;for(i;i<8;i++){P(semid,1);printf("print:\n");printf("a=%d\n",a);V(semid,0);}}int main(){pthread_t id1,id2;int ret1,ret2;key_t key;SEM_CTL_UN semctlarg1;SEM_CTL_UN semctlarg2;key=1;semid=semget(key,2,IPC_CREAT|0666);//创建semctlarg1.val=1;semctlarg2.val=0;semctl(semid,0,SETV AL,semctlarg1);//初始化semctl(semid,1,SETV AL,semctlarg2);ret1=pthread_create(&id1,NULL,thread1,NULL);ret2=pthread_create(&id2,NULL,thread2,NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);}4、实验结果实验结果截图如下:图1-1 线程同步三、实验心得通过本次实验,我掌握了Linux系统用户界面中键盘命令的使用,熟悉了Linux下的编程环境,进一步理解并掌握了线程的概念,了解了线程同步与通信的主要机制,并能通过信号灯操作实现线程间的同步和互斥。
华中科技大学计算机系统基础实验报告

课程实验报告课程名称:计算机系统基础专业班级:学号:姓名:指导教师:报告日期:2016年5月24 日计算机科学与技术学院目录实验1: (3)实验2: (13)实验3: (28)实验总结 (37)实验1:数据表示1.1 实验概述本实验的目的是更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。
实验中,你需要解开一系列编程“难题”——使用有限类型和数量的运算操作实现一组给定功能的函数,在此过程中你将加深对数据二进制编码表示的了解。
实验语言:c; 实验环境: linux1.2 实验内容需要完成bits.c 中下列函数功能,具体分为三大类:位操作、补码运算和浮点数操作。
1.3 实验设计源码如下:/** lsbZero - set 0 to the least significant bit of x* Example: lsbZero(0x87654321) = 0x87654320* Legal ops: ! ~ & ^ | + << >>* Max ops: 5* Rating: 1*/int lsbZero(int x) {//x右移一位再左移一位实现把最低有效位置0x = x>>1;x = x<<1;return x;}/** byteNot - bit-inversion to byte n from word x* Bytes numbered from 0 (LSB) to 3 (MSB)* Examples: getByteNot(0x12345678,1) = 0x1234A978* Legal ops: ! ~ & ^ | + << >>* Max ops: 6* Rating: 2*/int byteNot(int x, int n) {//x第n个字节每位都和1异或实现取反int y = 0xff;n = n<<3;y = y<<n;x = (x^y);return x;}/** byteXor - compare the nth byte of x and y, if it is same, return 0, ifnot, return 1* example: byteXor(0x12345678, 0x87654321, 1) = 1* byteXor(0x12345678, 0x87344321, 2) = 0* Legal ops: ! ~ & ^ | + << >>* Max ops: 20* Rating: 2*/int byteXor(int x, int y, int n) {//把x和y的第n个字节取出来异或,再转换为逻辑的0和1 n = n<<3;x = x>>n;y = y>>n;x = x&(0xff);y = y&(0xff);return !!(x^y);}/** logicalAnd - x && y* Legal ops: ! ~ & ^ | + << >>* Max ops: 20* Rating: 3*/int logicalAnd(int x, int y) {//把x和y分别转化为逻辑的0和1,再相与x = (!(!x))&(!(!y));return x;}/** logicalOr - x || y* Legal ops: ! ~ & ^ | + << >>* Max ops: 20* Rating: 3*/int logicalOr(int x, int y) {//把x和y分别转化为逻辑的0和1,再相或x = (!(!x))|(!(!y));return x;}/** rotateLeft - Rotate x to the left by n* Can assume that 0 <= n <= 31* Examples: rotateLeft(0x87654321,4) = 0x76543218 * Legal ops: ~ & ^ | + << >> !* Max ops: 25* Rating: 3*/int rotateLeft(int x, int n) {//先构造低n位为1,高(32-n)位为0的数z,x左移n位后的数加上x右移(32-n)位的数&z即可int z;z = ~(((1<<31)>>31)<<n);x = ((x>>(32+(~n+1)))&z)+(x<<n);return x;}/** parityCheck - returns 1 if x contains an odd number of 1's* Examples: parityCheck(5) = 0, parityCheck(7) = 1* Legal ops: ! ~ & ^ | + << >>* Max ops: 20* Rating: 4*/int parityCheck(int x) {//每次将数的低半数位与高半数位比较,再把y右移31位,最后把y转化为逻辑的0和1int y;y = x<<16;y = y^x;y = y^(y<<8);y = y^(y<<4);y = y^(y<<2);y = y^(y<<1);y = y>>31;return !(!y);}/** mul2OK - Determine if can compute 2*x without overflow * Examples: mul2OK(0x30000000) = 1* mul2OK(0x40000000) = 0** Legal ops: ~ & ^ | + << >>* Max ops: 20* Rating: 2*/int mul2OK(int x) {//把x第31位和30位分别和1做按位与,再异或,再和1异或int m;m = ((x>>31)&0x1)^((x>>30)&0x1);return m^0x1;}/** mult3div2 - multiplies by 3/2 rounding toward 0,* Should exactly duplicate effect of C expression (x*3/2),* including overflow behavior.* Examples: mult3div2(11) = 16* mult3div2(-9) = -13* mult3div2(1073741824) = -536870912(overflow)* Legal ops: ! ~ & ^ | + << >>* Max ops: 12* Rating: 2*/int mult3div2(int x) {//左移一位再+x即x*3,右移一位的时候,当y的最高位和最低位都为0时还要+1int y = (x<<1)+x;y = (y>>1)+(((y>>31)&1)&(((y<<31)>>31)&1));return y;}/** subOK - Determine if can compute x-y without overflow* Example: subOK(0x80000000,0x80000000) = 1,* subOK(0x80000000,0x70000000) = 0,* Legal ops: ! ~ & ^ | + << >>* Max ops: 20* Rating: 3*/int subOK(int x, int y) {//x的最高有效位和y的最高有效位不同且x和(x-y)的最高位不同才能判断溢出int m = (x>>31)&1;int n = (y>>31)&1;x = (m^n)&(m^(((x+(~y+1))>>31)&1));return (!x);}/** absVal - absolute value of x* Example: absVal(-1) = 1.* You may assume -TMax <= x <= TMax* Legal ops: ! ~ & ^ | + << >>* Max ops: 10* Rating: 4*/int absVal(int x) {//x最高位为0时就是x,最高位为1时是~x+1int y = x>>31;x = (y&(~x+1))+((~y)&x);return x;}/** float_abs - Return bit-level equivalent of absolute value of f for* floating point argument f.* Both the argument and result are passed as unsigned int's, but* they are to be interpreted as the bit-level representations of* single-precision floating point values.* When argument is NaN, return argument..* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 10* Rating: 2*/unsigned float_abs(unsigned uf) {int x=uf&(~(1<<31));if(x>0x7f800000){return uf;else return x;}/** float_f2i - Return bit-level equivalent of expression (int) f* for floating point argument f.* Argument is passed as unsigned int, but* it is to be interpreted as the bit-level representation of a* single-precision floating point value.* Anything out of range (including NaN and infinity) should return * 0x80000000u.* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30* Rating: 4*/int float_f2i(unsigned uf) {unsigned num=0x80000000;int x=(uf&0x007fffff)^0x00800000;int order=0;order=(uf&0x7f800000)>>23;if(order>158){return num;if(order<127) return 0;else if(((uf>>31)&1)==1){if(order>150){return ~(x<<(order-150))+1;}else return ~(x>>(150-order))+1;}else{if(order>150) return x<<(order-150);else return x>>(150-order);}}1.4 实验过程编写源码,运行btest,得出实验结果。
《计算机操作系统》课程设计

计算机操作系统课程设计1. 引言计算机操作系统是计算机科学与技术专业中一门重要的课程,它介绍了操作系统的基本概念、原理和设计方法,培养学生对计算机操作系统的理解和应用能力。
本文将介绍《计算机操作系统》课程设计的目标、内容和方法,并提供一些实用的学习资源和建议。
2. 课程设计目标《计算机操作系统》课程设计的主要目标是通过实践,帮助学生加深对操作系统概念和原理的理解,培养学生编写和调试操作系统的能力,提高解决实际问题的能力。
具体目标如下:- 理解操作系统的基本概念和原理; - 掌握操作系统的设计与实现方法; - 学会使用工具和技术进行操作系统的调试和测试;- 培养团队合作和解决问题的能力。
3. 课程设计内容《计算机操作系统》课程设计的内容包括以下几个方面:1. 进程管理:学生需要设计和实现一个简单的进程管理系统,包括进程的创建、调度和终止等功能,并实现进程间的通信和同步。
2. 文件系统:学生需要设计和实现一个简单的文件系统,包括文件的存储和管理、文件的读写等功能,并实现文件的保护和共享。
3. 内存管理:学生需要设计和实现一个简单的内存管理系统,包括内存的分配和释放、页面置换等功能,并实现进程的虚拟内存。
4. 设备管理:学生需要设计和实现一个简单的设备管理系统,包括设备的分配和释放、设备的控制和调度等功能,并实现设备的并发和互斥。
4. 课程设计方法《计算机操作系统》课程设计采用项目驱动的方法,学生将组成小组,每个小组负责完成一个操作系统的设计和实现。
具体方法如下: 1. 项目选择:学生可以自由选择他们感兴趣的项目,也可以从老师提供的项目中选择。
2. 项目计划:学生需要制定项目计划,包括项目的目标、任务和时间安排等。
3. 项目开发:学生按照项目计划开展项目开发工作,包括需求分析、系统设计、编码和测试等环节。
4. 项目评审:学生需要定期进行项目评审,包括项目进展、问题解决和改进措施等。
5. 项目展示:学生需要最后展示他们的项目成果,包括设计文档、源代码和演示等。
操作系统课程设计

华中科技大学计算机学院
16
Linux系统的相关知识
Linux版本
Linux通过简单的编号来区别内核的稳定版和开发 版。每个版本用三个数字描述,由圆点分隔。前两个数 表示版本号,第三个数表示发布号,如2.4.20。(2.6版 本和2.4版本在具体的操作细节上有很大差异)
如果第二个数为偶数,则表示稳定的内核;否则, 表示开发中的内核。
华中科技大学计算机学院
19
Linux系统的核心源码
Linux核心源代码位于/usr/src/linux下,包括:
arch: 包括所有和CPU类型相关的核心代码。它的每一个子目 录都代表一种支持的CPU类型,例如i386就是关于Intel CPU及 与之相兼容的体系结构的子目录,PC机一般都基于此目录;
2019/10/16
华中科技大学计算机学院
20
Linux系统的核心源码(续)
Linux核心源代码中的内容还包括:
设计目的
设计内容
实施方法及要求
时间安排
辅导
2019/10/16
华中科技大学计算机学院
4
设 计 内 容(1)
要求:熟悉和理解Linux编程环境
内容
1)编写一个C程序,实现文件拷贝功能。
2)编写一个C程序,使用Linux下的图形库,分窗口显 示三个并发进程的运行。
#include <curses.h>
华中科技大学计算机学院
14
内容简介
设计目的
设计内容
实施方法及要求
时间安排
辅导
2019/10/16
华中科技大学计算机学院
15
课程设计辅导
Linux系统的相关知识 以Redhat Linux 9.0为例
华科操作系统课设报告

华中科技大学操作系统课程设计实验报告专业:计算机科学与技术班级:1101姓名:许阳学号:U201014241一、实验目的掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法。
二、实验要求1、掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。
●编一个C程序,其内容为实现文件拷贝的功能;●编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。
要求用到Linux下的图形库。
2、掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。
另编写一个应用程序,调用新增加的系统调用。
实现的功能是:文件拷贝;3、掌握增加设备驱动程序的方法。
通过模块方法,增加一个新的设备驱动程序,其功能可以简单。
实现字符设备的驱动;4、了解和掌握/proc文件系统的特点和使用方法●了解/proc文件的特点和使用方法●监控系统状态,显示系统中若干部件使用情况●用图形界面实现系统监控状态。
5、设计并实现一个模拟的文件系统(选作)三、实验一1、编一个C程序,其内容为实现文件拷贝的功能要实现文件拷贝功能,主要用到的函数是open、write、read。
以前在windows下写C语言打开文件常用的fopen,此时不能用,因为fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api ;所以应该直接使用linux中的系统函数open。
主要用到的头文件:Unistd.h \\包含了许多Linux系统服务的函数原型,如:read、writeFcntl.h \\定义了很多宏和open,fcntl函数原型Stdio.h \\标准输入输出头文件sys/types.h \\此头文件包含适当时应使用的多个基本派生类型sys/stat.h \\包含了获取文件属性的一些函数errno.h \\用于调试错误代码是所需要的一些errno变量string.h \\包含了处理字符串的一些函数设计思路:由命令行参数获取2个文件名,根据其文件名和路径分别打开该2个文件,设置一个循环,从源文件复制N个字节到目的文件,直到源文件指针到文件尾,最后关闭2个文件。
操作系统课程设计报告

南华大学计算机科学与技术学院课程设计报告(20008 ~2009 学年度第一学期)课程名称操作系统课程设计项目名称文件管理系统姓名** 学号************** 专业班级地点教师一、设计任务及主要技术本设计的目的是通过设计和调试一个简单的文件系统,通过模拟文件操作命令的执行,来模拟文件管理,使学生对主要文件操作命令的实质和执行过程有比较深入的了解,掌握它们的基本实施方法。
具体要求如下:⑴设计一个支持n个用户的文件系统,每个用户可拥有多个文件;⑵采用二级或二级以上的多级文件目录管理;⑶对文件应设置存取控制保护方式,如“只能执行”、“允许读”、“允许写”等;⑷系统的外部特征应接近于真实系统,可设置下述文件操作命令:建立文件、打开文件、关闭文件、删除文件、读文件、写文件、复制文件、查询目录;⑸通过键盘使用该文件系统,系统应显示操作命令的执行结果。
二、设计方案:主要模仿和实现Windows中”我的电脑”的部分功能系统原理框图:一、实验源码:using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Collections;namespace FileDirOperate{///<summary>///与文件有关的操作类///</summary>public class FileOperate{///<summary>/// Deletes the file.///</summary>///<param name="FileFullPath">要删除的文件全路径</param>///<returns></returns>public bool DeleteFile(string FileFullPath){if (File.Exists(FileFullPath) == true){File.SetAttributes(FileFullPath, FileAttributes.Normal);File.Delete(FileFullPath);return true;}else{return false;}}///<summary>/// Gets the name of the file.包括文件的扩展名///</summary>///<param name="FileFullPath">文件的全路径</param>///<returns></returns>public string GetFileName(string FileFullPath){if (File.Exists(FileFullPath) == true){FileInfo F = new FileInfo(FileFullPath);return ;}else{return null;}}///<summary>/// Gets the name of the file.///</summary>///<param name="FileFullPath">文件的全路径</param>///<param name="IncludeExtension">是否包含文件的扩展名</param>///<returns></returns>public string GetFileName(string FileFullPath, bool IncludeExtension) {if (File.Exists(FileFullPath) == true){FileInfo F = new FileInfo(FileFullPath);if (IncludeExtension == true){return ;}else{return .Replace(F.Extension, "");}}else{return null;}}///<summary>///得到文件的大小///</summary>///<param name="info">FileInfo</param>///<returns></returns>public String getFileSize(FileInfo info){if (info.Exists == true){long FL =info.Length;if (FL > 1024 * 1024 * 1024){// KB MB GB TBreturn System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024 * 1024), 2)) + " GB";}else if (FL > 1024 * 1024){return System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024), 2)) + " MB";}else{return System.Convert.ToString(Math.Round((FL + 0.00) / 1024, 2)) + " KB"; }}else{return null;}}///<summary>///得到文件的后缀名///</summary>///<param name="info">FileInfo</param>///<returns></returns>public String getFileExtension(FileInfo info){if (info.Exists == true){String extension=info.Extension;return extension;//.Substring(1);// return extension.Substring(1, extension.Length - 1);}else{return null;}}///<summary>/// Gets the file extension.///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public string GetFileExtension(string FileFullPath){if (File.Exists(FileFullPath) == true){FileInfo F = new FileInfo(FileFullPath);return F.Extension;}else{return null;}}///<summary>/// Opens the file.///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public bool OpenFile(string FileFullPath){if (File.Exists(FileFullPath) == true){System.Diagnostics.Process.Start(FileFullPath);return true;}else{return false;}}///<summary>/// Gets the size of the file.///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public string GetFileSize(string FileFullPath){if (File.Exists(FileFullPath) == true){FileInfo F = new FileInfo(FileFullPath);long FL = F.Length;if (FL > 1024 * 1024 * 1024){// KB MB GB TBreturn System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024 * 1024), 2)) + " GB";}else if (FL > 1024 * 1024){return System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024), 2)) + " MB";}else{return System.Convert.ToString(Math.Round((FL + 0.00) / 1024, 2)) + " KB"; }}else{return null;}}///<summary>/// Files to stream byte.///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public byte[] FileToStreamByte(string FileFullPath){byte[] fileData = null;if (File.Exists(FileFullPath) == true){FileStream FS = new FileStream(FileFullPath, System.IO.FileMode.Open); fileData = new byte[FS.Length];FS.Read(fileData, 0, fileData.Length);FS.Close();return fileData;}else{return null;}}///<summary>/// Bytes the stream to file.///</summary>///<param name="CreateFileFullPath">The create file full path.</param>///<param name="StreamByte">The stream byte.</param>///<returns></returns>public bool ByteStreamToFile(string CreateFileFullPath, byte[] StreamByte){try{if (File.Exists(CreateFileFullPath) == true){DeleteFile(CreateFileFullPath);}FileStream FS;FS = File.Create(CreateFileFullPath);FS.Write(StreamByte, 0, StreamByte.Length);FS.Close();return true;}catch{return false;}}///<summary>///序列化XML文件///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public bool SerializeXmlFile(string FileFullPath){try{System.Data.DataSet DS = new System.Data.DataSet();DS.ReadXml(FileFullPath);FileStream FS = new FileStream(FileFullPath + ".tmp", FileMode.OpenOrCreate); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter FT = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();FT.Serialize(FS, DS);FS.Close();DeleteFile(FileFullPath);File.Move(FileFullPath + ".tmp", FileFullPath);return true;}catch{return false;}}///<summary>///反序列化XML文件///</summary>///<param name="FileFullPath">The file full path.</param>///<returns></returns>public bool DeserializeXmlFile(string FileFullPath){try{System.Data.DataSet DS = new System.Data.DataSet();FileStream FS = new FileStream(FileFullPath, FileMode.Open);System.Runtime.Serialization.Formatters.Binary.BinaryFormatter FT = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();((System.Data.DataSet)FT.Deserialize(FS)).WriteXml(FileFullPath + ".tmp"); FS.Close();DeleteFile(FileFullPath);File.Move(FileFullPath + ".tmp", FileFullPath);return true;}catch{return false;}}///<summary>///得到文件的创建时间///</summary>///<param name="info"></param>///<returns></returns>public String getFileCreateTime(FileInfo info){return info.CreationTime.ToString();}///<summary>///得到文件最后一次修改时间///</summary>///<param name="info"></param>///<returns></returns>public String getFileLastModifyTime(FileInfo info){return stWriteTime.ToString();}}///<summary>///与文件夹有关的操作类///</summary>public class DirOperate{public enum OperateOption{///<summary>///存在删除再创建///</summary>ExistDelete,///<summary>///存在直接返回///</summary>ExistReturn}///<summary>///创建文件夹///</summary>///<param name="DirFullPath">The dir full path.</param>///<param name="DirOperateOption">The dir operate option.</param>///<returns></returns>public bool CreateDir(string DirFullPath, OperateOption DirOperateOption) {try{if (Directory.Exists(DirFullPath) == false){Directory.CreateDirectory(DirFullPath);}else if (DirOperateOption == OperateOption.ExistDelete){Directory.Delete(DirFullPath, true);}return true;}catch{return false;}}///<summary>///删除文件夹///</summary>///<param name="DirFullPath">The dir full path.</param>///<returns>成功则为True 否则为False</returns>public bool DeleteDir(string DirFullPath){if (Directory.Exists(DirFullPath) == true){Directory.Delete(DirFullPath, true);return true;}{return false;}}///<summary>/// Gets the dir files.///</summary>///<param name="DirFullPath">The dir full path.</param>///<returns></returns>public string[] GetDirFiles(string DirFullPath){string[] FileList = null;if (Directory.Exists(DirFullPath) == true){FileList = Directory.GetFiles(DirFullPath, "*.*", SearchOption.TopDirectoryOnly);}return FileList;}///<summary>/// Gets the dir files.///</summary>///<param name="DirFullPath">The dir full path.</param>///<param name="SO">The SO.</param>///<returns></returns>public string[] GetDirFiles(string DirFullPath, SearchOption SO) {string[] FileList = null;if (Directory.Exists(DirFullPath) == true){FileList = Directory.GetFiles(DirFullPath, "*.*", SO); }return FileList;} ArrayList filelist = new ArrayList();public ArrayList getDirFiles(String DirFullpath, String pattern) {if (Directory.Exists(DirFullpath)){DirectoryInfo inf = new DirectoryInfo(DirFullpath);FileSystemInfo[] infos = inf.GetFileSystemInfos();foreach (FileSystemInfo info in infos){if (info is FileInfo){if(.Contains(pattern))filelist.Add(info.FullName);}else{if (.Contains(pattern))filelist.Add(info.FullName);getDirFiles(info.FullName, pattern);}}}return filelist;}///<summary>/// Gets the dir files.///</summary>///<param name="DirFullPath">The dir full path.</param>///<param name="SearchPattern">The search pattern.</param>///<returns>所有文件</returns>public string[] GetDirFiles(string DirFullPath, string SearchPattern) {string[] FileList = null;if (Directory.Exists(DirFullPath) == true){FileList = Directory.GetFiles(DirFullPath, SearchPattern);}return FileList;}///<summary>/// Gets the dir files.///</summary>///<param name="DirFullPath">The dir full path.</param>///<param name="SearchPattern">The search pattern.</param>///<param name="SO">The SO.</param>///<returns>与当前条件匹配的所有文件和文件夹</returns>public string[] GetDirFiles(string DirFullPath, string SearchPattern, SearchOption SO) {string[] FileList = null;if (Directory.Exists(DirFullPath) == true){FileList = Directory.GetFiles(DirFullPath, SearchPattern, SO);}return FileList;}///<summary>///得到文件的创建时间///</summary>///<param name="FileFullPath">文件的全路径</param>///<returns>文件的创建时间</returns>public String getFileCreateTime(String FileFullPath) {FileInfo info = new FileInfo(FileFullPath);if (info.Exists){return info.CreationTime.ToString();}else {return"";}}///<summary>///得到文件最后一次修改的时间///</summary>///<param name="FileFullPath">文件的全路径</param>///<returns>文件的最后修改时间</returns>public String getFileLastModifyTime(String FileFullPath) {if(File.Exists(FileFullPath)){return new FileInfo(FileFullPath).LastWriteTime.ToString();}else{return"";}}///<summary>///得到当前目录下的子目录或文件///</summary>///<param name="FileFullPath">目录或文件的完整路径</param>///<returns>当前目录的所有子目录和子文件</returns>public FileSystemInfo[] getFileSystemInfo(String FileFullPath) {if(Directory.Exists(FileFullPath)){DirectoryInfo info=new DirectoryInfo(FileFullPath);return info.GetFileSystemInfos();}else{return null;}}///<summary>///得到文件的创建时间///</summary>///<param name="info"></param>///<returns></returns>public String getDirCreationTime(DirectoryInfo info) {return info.CreationTime.ToString();}///<summary>///得到文件最后一次修改的时间///</summary>///<param name="info"></param>///<returns></returns>public String getDirLastModifyTime(DirectoryInfo info) {return stWriteTime.ToString();}///<summary>///保存文件夹的大小///</summary>private long length = 0;///<summary>///获得文件夹的大小///</summary>///<param name="info">文件夹实例</param>///<returns>文件夹大小</returns>public long getDirSize(DirectoryInfo info){if (info.Exists){FileSystemInfo[] infos = info.GetFileSystemInfos();foreach (FileSystemInfo inf in infos)//循环每一个目录里的每一个文件得到总的文件夹的大小{if (inf is DirectoryInfo) {length = +getDirSize((DirectoryInfo)inf);}else {length+=((FileInfo)inf).Length;//return length;}} return length;}else{return 0;}}///<summary>///循环得到文件夹的大小///</summary>///<param name="info">文件夹实例</param>///<returns>文件夹的大小</returns>public String getDirSizes(DirectoryInfo info){ long FL = 0; FL+=getDirSize(info); length = 0;if (FL > 1024 * 1024 * 1024)//将得到的位化为 KB/MB /GB{ // KB MB GB TBreturn System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024 * 1024), 2)) + " GB"+" ("+FL+" 字节)";}else if (FL > 1024 * 1024){ return System.Convert.ToString(Math.Round((FL + 0.00) / (1024 * 1024), 2)) + " MB" + " (" + FL + " 字节)";} else{return System.Convert.ToString(Math.Round((FL + 0.00) / 1024, 2)) + " KB" + " (" + FL + " 字节)"; } }}}****************************************************************************using System;using System.Collections.Generic;using System.Drawing;using System.Windows.Forms;using System.IO;using FileDirOperate;using System.Collections;using System.Text;namespace FileSystem{///<summary>/// Description of MainForm.///</summary>public partial class MainForm : Form{private bool flag = false;private bool flag1 = false;private Stack<String> back =new Stack<string>(50);//通过这两个栈来实现浏览文件时的前进与后退private Stack<String> forward = new Stack<string>(50);private int n=1;//用于复制文件或文件夹时自动生成名字private String olddirorfilepath=null;//原文件路径private String olddirname = null;//原文件名bool ishasone=true;//标志是否有改动的属性private bool isdir = false;//标志是否为目录private TextBox txtname = new TextBox();private CheckBox ckreadonly=new CheckBox();private CheckBox ckyingchang=new CheckBox();private CheckBox ckguidang=new CheckBox();[STAThread]public static void Main(string[] args){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new MainForm());}public MainForm(){//// The InitializeComponent() call is required for Windows Forms designer support.//InitializeComponent();this.skinEngine1.SkinFile="DiamondGreen.ssk";fillCombox();comboxbind();// filletree();PopulateTreeViews();//// TODO: Add constructor code after the InitializeComponent() call.////this.back.Push(boBox1.Text.Trim());this.splitContainer2.Panel2Collapsed = true;if (back.Count == 0) this.goback.Enabled = false;if (forward.Count == 0) this.goforward.Enabled = false;if (olddirorfilepath == null){paste.Enabled = false;}else {paste.Enabled = true;}}///<summary>///填充下拉列表框///</summary>private void fillCombox(){//获取当前系统的驱动器号DriveInfo[] info=DriveInfo.GetDrives();foreach(DriveInfo drive in info){boBox1.Items.Add();//Console.WriteLine(drive.VolumeLabel);}boBox1.SelectedIndex=1;}void Button5Click(object sender, EventArgs e){if(boBox1.Text.ToString().Equals("A:\\")){MessageBox.Show("请插入A盘!");return;}//清除listView中的所有项this.listView1.Items.Clear();String directoryname=boBox1.Text.ToString();DirectoryInfo info = new DirectoryInfo(directoryname);if (!info.Exists) {MessageBox.Show("找不到"+"'"+boBox1.Text.Trim()+"'"+"请确认路径,或Internet地址正确!","Microsoft InternetExploer",MessageBoxButtons.OK,MessageBoxIcon.Error);return;}this.back.Push(directoryname);fillListview(directoryname);}///<summary>///填充listView///</summary>///<param name="FullDirPath">要填充listview的目录路径</param>private void fillListview(String FullDirPath) {if (back.Count > 0) { this.goback.Enabled = true; } else { this.goback.Enabled = false; }if (forward.Count > 0) { this.goforward.Enabled = true; } else{this.goforward.Enabled = false; }DirOperate operate = new DirOperate();FileOperate fileoperate = new FileOperate();FileSystemInfo[] infos = operate.getFileSystemInfo(FullDirPath);if (null != infos){foreach (FileSystemInfo info in infos){if (info is DirectoryInfo)//循环获取每一个文件的信息并加入listView{ListViewItem item = new ListViewItem(new String[] { , "", "文件夹", operate.getDirCreationTime((DirectoryInfo)info),operate.getDirLastModifyTime((DirectoryInfo)info) },0);this.listView1.Items.Add(item);}if (info is FileInfo)//循环获取每一个文件的信息并加入listView{ListViewItem item = new ListViewItem(new String[] { , fileoperate.getFileSize((FileInfo)info), fileoperate.getFileExtension((FileInfo)info),fileoperate.getFileCreateTime((FileInfo)info),fileoperate.getFileLastModifyTime((FileInfo)info) },2);//为不同类型文件添加不同图标String extention = fileoperate.getFileExtension((FileInfo)info);if (extention == ".doc") { item.ImageIndex = 3; }if (extention == ".ini") { item.ImageIndex = 5; }if (extention == ".ppt") { item.ImageIndex = 4; }if (extention == ".log") { item.ImageIndex = 2; }this.listView1.Items.Add(item);}}}}//选择不同的显示方式void MenuitemIconClick(object sender, EventArgs e){this.listView1.View=rgeIcon;}void MenuitemlistClick(object sender, EventArgs e){this.listView1.View=View.List;}void DetailsClick(object sender, EventArgs e){this.listView1.View=View.Details;}///<summary>///双击文件或文件夹打开文件或文件夹///</summary>///<param name="sender"></param>///<param name="e"></param>private void listView1_DoubleClick(object sender, EventArgs e){fileDirOpen(); flag = true;}///<summary>///开文件或文件夹///</summary>private void fileDirOpen(){String path = boBox1.Text.ToString().Trim();String fullpath = bine(path,this.listView1.SelectedItems[0].Text.Trim());//得到当前目录的完整路径if (!this.listView1.SelectedItems[0].SubItems[2].Text.Trim().Equals("文件夹")) {try{System.Diagnostics.Process.Start(fullpath);}catch (Exception ex){ MessageBox.Show(ex.Message); return; }}else{boBox1.Text = fullpath;//将刚访问过的资源路径放入栈中this.back.Push(fullpath);this.listView1.Items.Clear();fillListview(fullpath);}}//选择不同的上下文菜单private void listView1_MouseClick(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Right){this.listView1.ContextMenuStrip = this.contextMenuStrip2;}}private void contextMenuStrip2_VisibleChanged(object sender, EventArgs e){this.listView1.ContextMenuStrip = this.contextMenuStrip1;}///<summary>///用菜单打开文件或文件夹///</summary>///<param name="sender"></param>///<param name="e"></param>private void filediropen_Click(object sender, EventArgs e){fileDirOpen();}//后退浏览private void goback_Click(object sender, EventArgs e){if (back.Count > 0){//this.back.Pop();flag1 = true;if (flag) { this.forward.Push(this.back.Pop()); flag = false; }if (back.Count > 0){String currentpath = this.back.Pop();this.forward.Push(currentpath);this.listView1.Items.Clear();fillListview(currentpath);boBox1.Text = currentpath;if (back.Count == 0) { this.goback.Enabled = false; }}}}//前进浏览private void goforward_Click(object sender, EventArgs e){if ( forward.Count > 0){//this.back.Pop();flag = true;if (flag1&&forward.Count>1) { this.back.Push(this.forward.Pop()); flag1 = false; }String currentpath = this.forward.Pop();this.back.Push(currentpath);this.listView1.Items.Clear();fillListview(currentpath);boBox1.Text = currentpath;if (forward.Count == 0) { this.goforward.Enabled = false; }}}//退出应用程序private void exit_Click(object sender, EventArgs e){Application.Exit();}//填充树private void filletree() {//String[] drives = DriveInfo.GetDrives();DriveInfo[]infos=DriveInfo.GetDrives();foreach (DriveInfo info in infos) {this.treeView1.Nodes.Add();if ( != "A:\\"){//String[] dirs = Directory.GetDirectories();// this.treeView1.Nodes[0].Nodes.Add(dirs[0]);}}}//使文件的文件名成可编辑状态,准备重命名private void filedirrename_Click(object sender, EventArgs e){belEdit = true;this.listView1.SelectedItems[0].BeginEdit();}//更改文件名字private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e){if (bel == null) return;else{String filename = bel;String oldpath = bine(boBox1.Text.Trim(),((ListView)sender).SelectedItems[0].Text);String path = bine(boBox1.Text.Trim(), filename);//得到新的名字if (!this.listView1.SelectedItems[0].SubItems[2].Text.Trim().Equals("文件夹")){FileInfo info = new FileInfo(path);if (info.Exists)//如果文件名已经存在,给出出错提示{MessageBox.Show("无法从命名文件" + bel + " " + "制定文件与现有文件同名,请另外指定文件名", "文件重命名错误", MessageBoxButtons.OK, MessageBoxIcon.Error);e.CancelEdit = true; return;}else{try{File.Move(oldpath, path);}catch(IOException exception){MessageBox.Show(exception.Message);return;}}return;}else{DirectoryInfo info = new DirectoryInfo(path);if (info.Exists) { MessageBox.Show("无法从命名文件夹" + bel + " " + "制定文件夹与现有文件夹同名,请另外指定文件夹名", "文件夹重命名错误", MessageBoxButtons.OK, MessageBoxIcon.Error); e.CancelEdit = true; return; }else{ //info.Create();Directory.Move(oldpath, path);//MessageBox.Show(oldpath + " " + path);}//MessageBox.Show(oldpath);return;}}}//填充treeviewprivate void PopulateTreeView1(){TreeNode rootNode;DirectoryInfo info = new DirectoryInfo(@"C:\Documents and Settings");if (info.Exists){rootNode = new TreeNode();rootNode.Tag = info;GetDirectories1(info.GetDirectories(), rootNode); treeView1.Nodes.Add(rootNode);}}//填充treeviewprivate void GetDirectories1(DirectoryInfo[] subDirs, TreeNode nodeToAddTo){TreeNode aNode;DirectoryInfo[] subSubDirs;foreach (DirectoryInfo subDir in subDirs){aNode = new TreeNode(,0,0);aNode.Tag = subDir;aNode.ImageKey = "folder";TreeNode node = new TreeNode(subDir.FullName);aNode.Nodes.Add(node);nodeToAddTo.Nodes.Add(aNode);}}private void PopulateTreeViews(){DriveInfo []infos = DriveInfo.GetDrives();foreach (DriveInfo info in infos){ if(!="A:\\")PopulateTreeView();}}private void PopulateTreeView(String s){TreeNode rootNode;DirectoryInfo info = new DirectoryInfo(s);if (info.Exists){rootNode = new TreeNode(,2,2);rootNode.Tag = info;TreeNode Node = new TreeNode(s);rootNode.Nodes.Add(Node);treeView1.Nodes.Add(rootNode);}private void GetDirectories(DirectoryInfo[] subDirs,TreeNode nodeToAddTo){}private void treeView1_AfterExpand(object sender, TreeViewEventArgs e){// String text = e.Node.Nodes[0].Text;String text = e.Node.FullPath;DirectoryInfo info = new DirectoryInfo(text);// MessageBox.Show(text);e.Node.Nodes.Clear();if (info.Exists){GetDirectories1(info.GetDirectories(), e.Node);}}private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {boBox1.Text = e.Node.FullPath;this.back.Push(e.Node.FullPath);this.listView1.Items.Clear();fillListview(e.Node.FullPath);}private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){if (boBox1.Text.Trim().Equals("A:\\")){MessageBox.Show("请插入A盘!");this.listView1.Items.Clear();return;}this.listView1.Items.Clear();this.back.Push(boBox1.Text.Trim());fillListview(boBox1.SelectedItem.ToString().Trim());}private void button1_Click(object sender, EventArgs e){this.splitContainer1.Panel1Collapsed = true;}private void fileshow_Click(object sender, EventArgs e){this.splitContainer1.Panel1Collapsed = false;this.splitContainer2.Panel2Collapsed = true;}private void createnewdir_Click(object sender, EventArgs e){String name="新建文件夹";if (listView1.Items.Count > 0){while (ishasone){foreach (ListViewItem items in this.listView1.Items){ // MessageBox.Show(items.Text);if (name.Equals(items.Text)){name = "新建文件夹";name = name + (n++);//MessageBox.Show(n.ToString());}else ishasone = false;}}}belEdit = true;ListViewItem item = new ListViewItem(new String[] { name, "", "文件夹", DateTime.Now.ToString(),DateTime.Now.ToString()}, 0);this.listView1.Items.Add(item);Directory.CreateDirectory(boBox1.Text.Trim() + "\\" + name);n = 1;ishasone = true;this.listView1.Items[this.listView1.Items.Count - 1].BeginEdit();}private void dirorfiledelete_Click(object sender, EventArgs e){Stringpath=bine(boBox1.Text.Trim(),this.listView1.SelectedItems[0].Text.ToString( ));if (this.listView1.SelectedItems[0].SubItems[2].Text.Trim().Equals("文件夹"))。
华科操作系统课设报告

华中科技大学操作系统课程设计实验报告专业:计算机科学与技术班级:1101:许阳学号:U202114241一、实验目的掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法。
二、实验要求1、掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。
●编一个C程序,其内容为实现文件拷贝的功能;●编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。
要求用到Linux下的图形库。
2、掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。
另编写一个应用程序,调用新增加的系统调用。
实现的功能是:文件拷贝;3、掌握增加设备驱动程序的方法。
通过模块方法,增加一个新的设备驱动程序,其功能可以简单。
实现字符设备的驱动;4、了解和掌握/proc文件系统的特点和使用方法●了解/proc文件的特点和使用方法●监控系统状态,显示系统中假设干部件使用情况●用图形界面实现系统监控状态。
5、设计并实现一个模拟的文件系统〔选作〕三、实验一1、编一个C程序,其内容为实现文件拷贝的功能要实现文件拷贝功能,主要用到的函数是open、write、read。
以前在windows下写C语言翻开文件常用的fopen,此时不能用,因为fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api ;所以应该直接使用linux中的系统函数open。
主要用到的头文件:Unistd.h \\包含了许多Linux系统效劳的函数原型,如:read、writeFcntl.h \\定义了很多宏和open,fcntl函数原型Stdio.h \\标准输入输出头文件sys/types.h \\此头文件包含适当时应使用的多个根本派生类型sys/stat.h \\包含了获取文件属性的一些函数errno.h \\用于调试错误代码是所需要的一些errno变量string.h \\包含了处理字符串的一些函数设计思路:由命令行参数获取2个文件名,根据其文件名和路径分别翻开该2个文件,设置一个循环,从源文件复制N个字节到目的文件,直到源文件指针到文件尾,最后关闭2个文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
华中科技大学嵌入式操作系统课程设计实验报告院系: 计算机科学与技术学院专业:班级:姓名:指导老师:报告时间:计算机科学与技术学院目录1.课程设计目的 (3)2.课程设计环境搭建 (3)3.内容一:熟悉和理解Linux编程环境3.1 内容要求 (5)3.2 设计过程及实现 (5)4.内容二:掌握添加系统调用的方法4.1 内容要求 (9)4.2 设计过程及实现 (9)5.内容三:掌握添加设备驱动程序的方法5.1 内容要求 (17)5.2 设计过程及实现 (17)6.内容四:理解和分析/proc文件6.1 内容要求 (22)6.2 设计过程及实现 (22)1 课程设计目的(1)掌握Linux操作系统的使用方法;(2)了解Linux系统内核代码结构;(3)掌握实例操作系统的实现方法。
2 课程设计环境搭建(1)windows 7上,利用虚拟机软件VMware软件搭建的linux平台:◎Ubuntu 11.10 (安装包:ubuntu-11.10-desktop-i386)◎内核:linux-headers-3.0.0-12-generic(2)更改root登录:在现阶段Ubuntu的系统中,是不允许直接以root身份登录系统的,但是在做课设的过程中,需要大量的使用root权限来进行命令的操作。
如果以普通用户登录ubuntu,会连编辑一个文件都非常周折。
为此,我找到了一种修改系统文件,以达到直接使用root身份登录的方法:◎开始的时候,只能以普通用户登录,用Ctrl+Alt+T打开终端:初始化/修改root密码sudo passwd root用vi编辑器修改这个文件:sudo vi /etc/lightdm/lightdm.conf在文件最后加入这么一行代码:greeter-show-manual-login=true然后保存退出,sudo reboot 重启系统。
之后就可以输入root用户登录。
(3)在添加系统调用中用到的其他内核包:◎下载和当前实验环境最为接近的系统版本(这点很重要)使用apt-get install linux-source-3.0.0 命令,◎下载结果是linux-source-3.0.0.tar.bz2◎解压命令:tar –xjvf linux-source-3.0.0.tar.bz2 –C /usr/src ◎解压后,在/usr/src目录下得到内核文件夹linux-source-3.0.0(4)在调用linux图形库时需要安装GTK环境:◎安装gcc/g++/gdb/make 等基本编程工具apt-get install build-essentialTip:如果提示由于依赖项不能安装,需要使用apt的强化版aptitude,这个工具可以自动分析软件包依赖,系统一般不自带,需要先安装,具体过程是:apt-get install aptitudeaptitude install build-essentialaptitude这个工具很强大,对于解决软件包安装时的依赖问题很有帮助。
◎安装 libgtk2.0-dev libglib2.0-dev 等开发相关的库文件:apt-get install gnome-core-devel◎安装GTK核心组件:apt-get install libgtk2.0-dev这个安装完成后,GTK环境就基本搭建成功,网上有些教程说要安装其他配置文件,经我亲测,发现只要安装libgtk2.0-dev这个包就能搞定。
3 内容一:熟悉和理解Linux编程环境3.1 内容要求(1)编写一个C程序,实现文件拷贝功能(2)编写一个C程序,使用Linux下的图形库,分窗口显示三个并发进程运行;3.2 设计过程及实现(1)文件拷贝:①文件的拷贝主要的思想就是利用文件指针操作,在两个文件之间进行按字符的fget和fput。
从而完成整个文件的拷贝操作。
在这个基本功能之外,需要增加程序的健壮性,具体有以下几个方面:·源文件是否存在且能读取数据;·是否能创建目的文件,且能向里面写入数据;·程序需要的argc参数个数是否满足要求;②基于以上几点和内容要求,主要的程序段如下:if(argc!=3) //判断参数个数是否为3 ,否则返回{printf("Error in argc!\n");return 0;}if( (fsource=fopen(argv[1],"rb"))==NULL ){printf("Error in open source file!\n"); //判断源文件是否能打开和读出return 0;}if( (ftarget=fopen(argv[2],"wb"))==NULL ){printf("Error in open target file!\n"); //判断目的文件时候能创建和写入return 0;}while((c=fgetc(fsource))!=EOF){fputc(c,ftarget); //按字符读取和写入数据}③执行结果如下:将source/source.txt文件拷贝到到target.txt,开始时如下图3-1所示:图3-1 复制开始前source/source.txt文件内容利用mycopy程序复制,查看target.txt文件复制结果如下图3-2所示:图3-2 复制后target.txt文件的具体内容(2)实现三个进程之间的并发程序:这里需要用到课程实验时的fork( )程序以及GTK的图形显示。
①基本fork()程序,调用显示一个父进程和两个子进程的结构如下:if((pid_1=fork())==0){printf("Child 1# is running......\n"); //第一个子进程Child 1#show(argc,argv,"This is Child 1#"); //调用函数显示窗口}else{if((pid_2=fork())==0){printf("Child 2# is running......\n"); //第二个子进程Child 2#show(argc,argv,"This is Child 2#"); //调用函数显示窗口}else {printf("Parent # is running......\n"); //父进程Parent #//由于父进程需要显示全部子进程PID,所以这里直接用参数画窗口}}②调用GTK显示窗体函数模块的结构:void show(int argc,char *argv[ ],char *title ) {gtk_init (&argc, &argv); //初始化工具包并且获取命令行参数;window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //创建新的窗口;//设定窗口的位置;gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);//监听窗口的destroy事件;g_signal_connect (G_OBJECT (window),"destroy", G_CALLBACK (destroy_progress), NULL);gtk_window_set_title (GTK_WINDOW (window), title);//用来设定更改窗口标题;gtk_container_set_border_width (GTK_CONTAINER (window), 20);//设定宽度;//使用gtk_vbox_new函数建立纵向组装盒;//为了显示构件,必须将构件放入组装盒中,并将组装盒放在窗口内;vbox = gtk_vbox_new (FALSE, 10);gtk_container_set_border_width (GTK_CONTAINER (vbox), 100);//设定宽度;gtk_container_add (GTK_CONTAINER (window), vbox);gtk_widget_show (vbox);//使用gtk_box_pack_start函数将构件放到组装盒中;sprintf (id_char, "%s ,My ID:%d", title,getpid ()); //显示PID号label = gtk_label_new (id_char);gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 10);gtk_widget_show (label);sprintf (id_char, "父进程ID:%d", getppid ()); //显示PPID号label = gtk_label_new (id_char);gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 10);gtk_widget_show (label);button = gtk_button_new_with_label ("close"); //关闭窗口按钮//信号登记函数,监听按钮的clicked事件。
//当窗口clicked时,gtk_widget_destroy 就会被调用。
//而gtk_widget_destroy 函数又调用gtk_main_quit() 结束程序运行。
g_signal_connect_s (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), window);gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 10);GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);gtk_widget_grab_default (button);//函数显示窗口中的组件gtk_widget_show (button);gtk_widget_show (window);//准备将窗口和所有的组件显示在屏幕上,函数必须在GTK程序的最后调用.gtk_main ();}③编译代码forkgtk.c,运行;编译命令为:gcc -o forkgtk forkgtk.c `pkg-config --cflags --libs gtk+-2.0`程序运行结果如下图3-3所示:图3-3 三个并行显示窗口4.内容二:掌握添加系统调用的方法4.1 内容要求(1)采用编译内核的方法,添加一个新的系统调用。