操作系统实验报告5

更新时间:2023-11-08 06:31:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《操作系统 》实验报告

实验序号: 3 实验项目名称:Windows基本进程管理 学 号 实验地点 1207122219 1-418 姓 名 指导教师 邝沃佳 李远敏 专业、班 实验时间 软金二班 2014/11/17 一、实验目的及要求 通过观察任务管理器,来观察各个进程的动态信息。 二、实验设备(环境)及要求 (1) 一台WindowsXP操作系统的计算机。 (2) 计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 三、实验内容与步骤 1、 预备知识 ·任务管理器,了解用户计算机上正在运行的程序和进程的相关信息。 ·Windows环境中的编程。 1)线程创建 Create Thread()完成线程的创建。它在调用进程的地址空间上创建一个线程,执行指定的函数,并返回新建立线程的句柄。 原型: HANDLE CreateThead( LPSECURITY ATTRIBUTES lpThreadAttributes, //安全属性指针 DWORD dwStackSize, //线程堆栈大小 LPTHREAD STAPT ROUTINE lpStartAddress, //线程所要执行的函数 LPVOID lpParameter, //线程对应函数要传递的参数 DWORD dwCreationFlags, //线程创建后所处的状态 LPDWORD lpThreadId, //线程标识符指针 ); 参数说明: (1)lpThreadAttributes:为线程指定安全属性。为NULL时,线程得到一个默认的安全描述符。 (2)dwStackSize;线程堆栈的大小。其值为0时,其大小与调用该线程的线程堆栈大小相同。 (3)lpStartAddress:指定线程要执行的函数。 (4)lpParameter:函数中要传递的参数。 (5)dwCreationFlags:指定线程创建后所处的状态。若为CREATE SUSPENDED,表示创建

后处于挂起状态,用ResumeThread()激活后线程才可执行。若该值设为0,表示线程创建后立即执行。

(6)lpThreadId:用一个32位的变量接收系统返回的线程标识符,若该值设为NULL,系

统不返回线程标识符。 返回值:

如果线程创建成功,将返回该线程的句柄;如果失败,系统返回NULL, 可以调用函数GetLastError查询失败的原因。 用法举例:

static HANDLE hHandle1= NULL; //用于存储线程返回句柄的变量 DWORD dwThreadID1; //用于存储线程标识符的变量 // 创建一个名为ThreadName1的线程

hHandle1= CreateThread(LPSECURITY ATTRIBUTES)NULL, 0,

(LPTHREAD STAPT ROUTINE)ThreadNamel, (LPVOID)NULL, 0,&dwThreadID1); 2)撤销线程

ExitThread();用于撤销当前线程。 原型:

VOID ExitThread(

DWORD dwExitCode //线程返回码 );

参数说明:

dwExitCode:指定线程返回码,可以调用GetExitCodeThread()查询返回码的含义。 返回值:

该函数没有返回值。 用法举例:

ExitThread(0); //参数0表示要撤销进程中的所有线程 3)终止线程

TerminateThread()用于终止当前线程。该函数与ExitThread()的区别在于, ExitThread()在撤销线程时将该线程所拥有的资源全部归还给系统,而 TerminateThread()不归还资源。 原型:

BOOL TerminateThread(

HANDLE hThread, //线程句柄 DWORD dwExitCode //线程返回码 );

参数说明:

(1)hThread:要终止线程的线程句柄。

(2)dwExitCode:指定线程返回码,可以调用GetExitCodeThread()查询返回码的含义。

返回值:

函数调用成功,将返回一个非0值;若失败,返回0,可以调用函数GetLastError()查询失败的原因。 4)挂起线程

Sleep()用于挂起当前正在执行的线程。 原型:

VOID Sleep(

DWORD dwMilliseconds //挂起时间 );

参数说明:

dwMilliseconds:指定挂起时间,单位为ms(毫秒)。 返回值:

该函数无返回值。 5)关闭句柄

函数CloseHandle()用于关闭已打开对象的句柄,其作用与释放动态申请的内存空间类似,这样可以释放系统资源,使进程安全运行。 原型:

BOOL CLoseHandle(

HANDLE hObject // 要关闭对象的句柄 );

参数说明:

hObject:已打开对象的句柄。 返回值:

如果函数调用成功,则返回值为非0值;如果函数调用失败,则返回值为0。若要得到更多的错误信息,调用函数GetLastError()查询。

3、实验内容

使用系统调用CreatThread()创建一个子线程,并在子线程序中显示:Thread is Runing!。为了能让用户清楚地看到线程的运行情况,使用Sleep()使线程挂起5s,之后使用ExitThread(0)撤销线程。

4、实验要求

能正确使用CreatThread()、ExitThread()及Sleep()等系统调用,进一步理解进程与线程理论。

5、实验指导

本实验在WindowsXP、Microsoft Visual C++ 6.0环境下实现,利用Windows SDK(System Development Kit)提供的API(Application Program Interface,应用程序接口)完成程序的功能。实验在WindowsXP环境下安装Microsoft Visual C++ 6.0后进行,由于Microsoft Visual C++ 6.0是一个集成开发环境,其中包含了Windows SDK所有工具和定义,所以安装了Microsoft Visual C++ 6.0后不用特意安装SDK。实验中所有的API

是操作系统提供的用来进行应用程序开发的系统功能接口。 (1)首先启动安装好的Microsoft Visual C++ 6.0。

(2)在Microsoft Visual C++ 6.0环境下选择File→New命令,然后在Project选项卡

中选择Win32 Console Application建立一个控制台工程文件。

(3)由于CreatThread()等函数是Microsoft Windows操作系统的系统调用,因此选

择An application that supports MFC,之后单击Finish按钮.

(4)之后将打开Microsoft Visual C++ 6.0编辑环境,按本实验的要求编辑C程序,之后

编译、链接并运行该程序即可。

6、 实验总结

在Windows系统中进程是资源的拥有者,线程是系统调度的单位。进程创建后,其主线程也随即被创建。在该实验中,又创建了一个名为ThreadNamel的子线程,该子线程与主线程并发的被系统调度。为了能看到子线程的运行情况,在主线程创建子线程后,将主线程挂起5s以确保子线程能够运行完毕,之后调用Exit Thread(0)将所有线程(包括主、子线程序)撤销。

7、实验展望

可以进一步完善程序功能,请思考以下问题。

(1)如何向线程对应的函数传递参数?一个参数如何传递,多个参数又如何传递? (2)深入理解线程与进程的概念,在Windows环境下何时使用进程,何时使用线程?

实验六 线程的同步

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 函数描述 访问 WAIT ABANDONED WAIT OBJECT 0 WAIT TIMEOUT

描述

等待的对象是一个互斥(Mutex)对象,该互斥对象没有被拥有它的线程释放,它被设置为不能被唤醒 指定对象被唤醒 超时

用法举例:

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 各参数描述 访问 WAIT OBJECT 0 to(WAIT OBJECT 0+nCount-1) 描述 若bWaitAll为TRUE,返回值说明所有被等待的对象均被唤醒;若bWaitAll为FALSE,返回值减去WAITOBJECT 0说明lpHandles数组下标指定的对象满足等待条件。如果调用时多个对象同时被唤醒,则取多个对象中最小的那个数组下标 若bWaitAll为TRUE,返回值说明所有被等待的对象均被唤醒,并且至少有一个对象是没有约束的互斥对象;若bWaitAll为FALSE,返回值减去WAIT ABANDONED0说明lpHandles数组下标指定的没有约束的互斥对象满足等待条件 超时且参数bWaitAll指定的条件不能满足 WAIT ABANDONED 0 to(WAIT ABANDONED 0+nCount-1) WAIT TIMEOUT ②信号量对象(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 访问状态

访问

SEMAPHORE ALL ACCESS SEMAPHORE MODIFY STATE SYNCHRONIZE

描述

可以进行任何对信号量的访问

可使用ReleaseSemaphore()修改信号量的值,使信号量成为可用状态

使用等待函数(wait functions),等待信号量成为可用状态

(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

2、 实验编程

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

#include #include using namespace std; DWORD WINAPI Func(LPVOID p); typedef struct {

int firstArgu; long secArgu; }MyType,* pMyType; void main()

{ MyType MyTypeArgu={0}; MyTypeArgu.firstArgu=1; MyTypeArgu.secArgu=100000000; CreateThread(NULL,0,Func,&MyTypeArgu,0,NULL); Sleep(5000); cout<<\该线程已删除……\ ExitThread(0); } DWORD WINAPI Func(LPVOID p) { MyType param={0}; MoveMemory(¶m,p,sizeof(param)); int intValue=param.firstArgu; long longValue=param.secArgu; cout<<\,线程正在运行,5秒钟后该线程自动删除\cout<<\现在输出该线程函数传递的两个参数\cout<<\cout<<\请等待……\return 0; } 四、程序调试(结果及分析) 五、总结与体会 六、教师评语 签名: 日期:

成绩

本文来源:https://www.bwwdw.com/article/7532.html

Top