操作系统原理-文件管理实验

时间:2024.3.31

广州大学学生实验报告

开课学院及实验室:计算机科学与工程实验室                                   20141211

一、实验目的

了解Linux/Unix下文件管理的基本操作,基本文件读写命令。

二、实验器材

1、计算机一台。

2、Mac OS X

三、实验内容

1.简单的I/O流操作:备份文件

利用函数fopen(), fread(), fwrite(), fclose() 来实现简单的文件备份, 即将一个文件的内容拷贝到另一个文件中去。

四、实验步骤、记录和结果

源代码有错,不能正常运行,使用纯C语言,修改正如下。

新增代码为黄色底色        新增注释为绿色底色

#include <sys/types.h>

#include <stdio.h>

#define BUF_SIZE 1024

int main(void)

{

    char buf[BUF_SIZE];

    FILE *source, *backup;

   

    if(!(source=fopen("source.dat", "r")))  //以只读方式打开文件sourc.dat

    {

        printf("Error in opening file.\n");

        exit(1);

    }

   

    if(!(backup=fopen("backup.dat", "w")))  //以只写方式打开文件backup.dat

    {

        printf("Error in creating file.\n");

        exit(1);

    }

    //while(fread(buf, sizeof(buf), 1, source)==1)

    unsigned long readNum = 0;      //已读取字符数

    while((readNum = fread(buf, sizeof(char), sizeof(buf), source)))    //若读入的字符大于0,循环读写

    {

        fwrite(buf, sizeof(char),readNum, backup);      //写入文件

        //if(fwrite(buf, sizeof(buf), 1,backup))

        if (ferror(backup))       //判断是否出现写入错误

        {

            printf("Error in wrinting file.\n");

            exit(1);

        }

    }

   

    //if(ferror(source)==0)

    if (ferror(source))       //判断是否读取错误

    {

        printf("Error in reading file.\n");

        exit(1);

    }

    //if(!fclose(source))

    if(fclose(source))      //关闭源文件流

    {

        printf("Error in close file.\n");

        exit(1);

    }

    if(fclose(backup))     //关闭备份文件流

    {

        printf("Error in close file.\n");

        exit(1);

    }

    return 0;

}

运行代码:

提供测试的源文件为只有16bytes的字符。

编译运行程序。

检验两个文件MD5值,相同,证明是正确复制了文件。如下图所示:

结果分析:

原代码主要错误在于fwrite和fread的使用不正确。

引用网上资料,对fread的定义说明如下:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

Parameters

ptr

    Pointer to a block of memory with a size of at least (size*count) bytes, converted to a void*.

size

    Size, in bytes, of each element to be read.

    size_t is an unsigned integral type.

count

    Number of elements, each one with a size of size bytes.

    size_t is an unsigned integral type.

stream

    Pointer to a FILE object that specifies an input stream.

Return Value

The total number of elements successfully read is returned.

If this number differs from the count parameter, either a reading error occurred or the end-of-file was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror and feof, respectively.

If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged.

size_t is an unsigned integral type.

--------------------------------------------------------------------------------------------------------------

在原代码 while(fread(buf, sizeof(buf), 1, source)==1) 中,

由于sizeof(buf)为1024,即每次读取块大小为1024比特的数据,由于源文件只有16比特,不足1024,返回值为0,因此永远不满足循环条件。

修正如下,即可获得正确的读取比特数

readNum = fread(buf, sizeof(char), sizeof(buf), source);

写入文件fwrite()亦是同理。

循环条件改成while (!feof(source))亦可得到相同的结果。

为了验证程序的正确性,这次提供测试文件大于1k

再次运行程序,检验MD5值,证明正确无误。

心得体会

这次的实验较为简单,fread(),fwrite()等的使用虽然不难,但是却容易让人犯错误。

让我懂得即使看似简单的函数,也要仔细了解其说明文档,才能避免犯”低级“错误,以免造成难以发现的bug,甚至严重后果。


第二篇:操作系统原理实验五


实验五    线程的同步

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所示。

   返回值:

如果成功返回,其返回值说明是何种事件导致函数返回。

表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所示。

表2-2    各参数描述

②  信号量对象(Semaphore)

信号量对象(Semaphore)包括创建信号量(CreateSemaphore())、打开信号量(OpenSemaphore())及增加信号量的值(ReleaseSemaphore())API函数。

1) 创建信号量

CreateSemaphore())用于创建一个信号量。

原型:

HANDLE CreateSemaphore(

LPSECURITY ATTRIBUTES lpSemaphoreAttributes,  //安全属性

LONG lInitialCount,                           //信号量对象的初始值

   LONG lMaximumCount,                           //信号量的最大值

LPCTSTR  lpName                                //信号量名

);

参数说明:

(1)lpSemaphoreAttributes:指定安全属性,为NULL时,信号量得到一个

默认的安全描述符。

(2)   lInitialCount:指定信号量对象的初始值。该值必须大于等于0,小于等于lMaximumCount。当其值大于0时,信号量被唤醒。当该函数释放了一个等待该信号量的线程时,lInitialCount值减1,当调用函数ReleaseSemaphore()时,按其指定的数量加一个值。

(3)   lMaximumCount:指出该信号量的最大值,该值必须大于0。

(4)   lpName:给出信号量的名字。

返回值:

信号量创建成功,将返回该信号量的句柄。如果给出的信号量名是系统已经存在的信号量,将返回这个已存在信号量的句柄。如果失败,系统返回NULL,可以调用函数GetLastError()查询失败的原因。

用法举例:

Static HANDLE hHandlel= NULL;             //定义一个句柄

//创建一个信号量,其初始值为0,最大值为5,信号量的名字为“SemphoreNamel”

HHandle=CreateSemaphore(NULL,0,5,“SemphoreNamel”);

2) 打开信号量

OpenSemaphore()用于打开一个信号量。

原型:

 HANDLE OpenSemaphore(

DWORD dWDesiredAccess,     //访问标志

BOOL bInheritHandle,       //继承标志

LPCTSTR lpName              //信号量名

);

参数说明:

(1)   dwDesiredAccess:指出打开后要对信号量进行何种访问,如表2-3所示。

表2-3  访问状态

(2)bInheritHandle:指出返回的信号量句柄是否可以继承。

(3)lpName:给出信号量的名字。

返回值:

信号量打开成功,将返回该号量的句柄;如果失败,系统返回NULL,可以调用函数GetLastError()查询失败的原因。

用法举例:

static  HANDLE hHandlel= NULL ;

//打开一个名为“SemphoreNamel”的信号量,之后可使用ReleaseSemaphore()函数增加信号量的值hHandlel= OpenSemaphore(SEMAPHORE MODIFY STATE,NULL,“SemphoreNamel”);

3) 增加信号量的值

 ReleaseSemaphore()用于增加信号量的值。

原型:

BOOL ReleaseSemaphore(

HANDLE hSemaphore,            //信号量对象句柄

LONG lReleaseCount,           //信号量要增加数值

LPLONG lpPreviousCount          //信号量要增加数值的地址

);

参数说明:

(1)   hSemaphore:创建或打开信号量时给出的信号量对象句柄。Windows NT中建议要使用SEMAPHORE MODIFY STATE访问属性打开该信号量。

(2)   IReleaseCount:信号量要增加的数值。该值必须大于0。如果增加该值后,大于信号量创建时给出的lMaximumCount值,则增加操作失效,函数返回FALSE。

(3)   LpPreviousCounte:接收信号量值的一个32位的变量。若不需要接收该值,可以指定为NULL。

返回值:

如果成功,将返回一个非0值;如果失败,系统返回0,可以调用函数GetLastError()查询失败的原因。

用法举例:

static  HANDLE hHandlel= NULL;

BOOL rc;

Rc= ReleaseSemaphore(hHandlel,l,NULL);  //给信号量的值加1

3、    实验内容

完成主、子两个线程之间的同步,要求子线程先执行。在主线程中使用系统调用GreateThread()创建一个子线程。主线程创建子线程后进入阻塞状态,直到子线程运行完毕后唤醒主线程。

4、    实验要求

能正确使用等待对象WaitForSingleObject()或WaitForMultipleObject()及信号量对象CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()等系统调用,进一步理解线程的同步。

5、    实验指导

具体操作过程:在Microsoft Visual C++ 6.0环境下建立一个MFC支持的控制台工程文件,编写C程序,在程序中使用CreateSemaphore(NULL,0,1,“SemaphoreNamel”)创建一个名为“SemaphoreNamel”的信号量,信号量的初始值为0,之后使用0penSemaphore(SYNCHRONIZE|SEMAPHOSE MODIFY STATE,NULL,“SemaphoreNamel”)打开该信号量,这里访问标志用“SYNCHRONIZE|SEMAPHORE MODIFY STATE”,以便之后可以使用WaitForSingleObject()等待该信号量及使用ReleaseSemaphore()释放该信号量,然后创建一个子线程,主线程创建子线程后调用WaitForSingleObject(hHandlel,INFINITE),这里等待时间设置为INFINITE表示要一直等待下去,直到该信号量被唤醒为止。子线程结束,调用ReleaseSemaphore(hHandlel,1,NULL)释放信号量,使信号量的值加1。

6、    实验总结

该实验完成了主、子线程的同步,主线程创建子线程后,主线程阻塞,让子线程先执行,等子线程执行完毕后,由子线程唤醒主线程。

7、    实验展望

上面的程序完成了主、子两个线程执行先后顺序的同步关系,思考以下问题。

(1)   如何实现多个线程的同步?

(2)   若允许子线程执行多次后主线程再执行,又如何设置信号量的初值?

更多相关推荐:
操作系统原理实验报告(最终版)

键入文字课程名称学院专业班姓名学号指导教师XX学校实验报告20xx年3月目录实验1进程管理3一实验目的3二实验内容3三实验要求3四程序说明和程序流程图4五程序代码5六程序运行结果及分析7七指导教师评议8实验2进...

操作系统原理实验报告01

操作系统原理实验报告实验序号1实验项目名称Windows文件操作命令

操作系统原理实验报告02

操作系统原理实验报告实验序号2实验项目名称Windows基本进程管理

操作系统原理实验报告

操作系统原理实验报告一课程设计的题目根据操作系统原理课程的课堂教学内容结合自己的知识积累情况题目可从下述拟题中选择亦可自定二实验设计的内容在Linux或Windows操作系统下用C语言进行操作系统相关的设计开发...

操作系统原理与Linux_进程管理实验报告

计算机科学与技术系实验报告实验名称班级计算机082学号08034050217姓名XXXX20xx年03月23日实验二进程管理一实验目的1加深对进程概念的理解明确进程和程序的区别2进一步认识并发执行的实质3分析进...

操作系统原理---进程调度实验报告

一实验目的通过对进程调度算法的设计深入理解进程调度的原理进程是程序在一个数据集合上运行的过程它是系统进行资源分配和调度的一个独立单位进程调度分配处理机是控制协调进程对CPU的竞争即按一定的调度算法从就绪队列中选...

操作系统原理实验报告05

操作系统原理实验报告实验序号5实验项目名称线程的同步

操作系统原理实验指导书(软件)

《操作系统原理》课程实验指导书编写人:软件工程系辽宁工程技术大学软件学院20##年10月10日目录实验一进程同步与互斥......................1实验二银行家算法实现资源分配.........…

计算机操作系统实验报告

计算机操作系统实验报告,内容附图。

计算机操作系统实验课实验报告

实验报告实验课程计算机操作系统学生姓名XXX学号专业班级软件20xx年12月25日目录3实验一熟悉WindowsXP中的进程和线程实验二进程调度7实验三实验四死锁避免银行家算法的实现16存储管理22实验一熟悉W...

操作系统 内存管理实验报告

同组同学学号同组同学姓名注实验内容及步骤项目的内容如果较多可以加附页

操作系统内存管理实验报告

实验报告12345678910111213

操作系统原理实验报告(27篇)