操作系统原理课程的实验报告汇总
实验三:线程的创建与撤销
实验环境:计算机一台,内装有VC++、office等软件
实验日期:2024.4.11
实验要求:
1.理解:Windows系统调用的基本概念,进程与线程的基本概念。
2.掌握:使用Windows系统调用创建与撤销线程的方法。
实验内容:
1.使用Windows系统提供的系统调用创建线程。
2.使用Windows系统提供的系统调用撤销线程。
3.使用Windows系统提供的系统调用挂起线程。
实验源代码
// 实验三:线程的创建与撤销.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "实验三:线程的创建与撤销.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// The one and only application object
CWinApp theApp;
using namespace std;
void ThreadName1();
static HANDLE hHandle1 = NULL;
DWORD dwThreadID1;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
hHandle1 = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) ThreadName1,
(LPVOID) NULL,
0,
&dwThreadID1);
Sleep(5000);
CloseHandle(hHandle1);
ExitThread(0);
return nRetCode;
}
void ThreadName1()
{
printf("xiancheng is Running\n");
}
实验总结:
代码没有任何问题,过编译不过运行是因为将VC++安装在了C盘,权限不够,将其重新安装在D盘即成功运行。
对于代码的一些注释:
HANDLE类型的hHandle1是用于存储线程返回句柄的变量
DWORD类型的dwThreadID1是用于存储线程标识符的变量
创建操作:CreateHandle方法中共需要6个变量,本次代码中第三个变量为创建一个名为ThreadName1的线程
挂起操作:Sleep(5000);将主线程挂起5秒
CloseHandle方法用于关闭句柄
撤销操作:ExitThread(0)方法用于撤销所有线程
实验四:线程的同步
实验环境:计算机一台,内装有VC++、office等软件
实验日期:2024.4.26
实验要求:
1.理解:线程同步的基本概念。
2.掌握:使用线程同步API实现多线程同步的方法。
实验内容:
1.使用Windows系统提供的系统调用创建与撤销线程。
2.使用Windows系统提供的线程同步API实现多线程同步。
3.使用Windows系统提供的线程同步API解决实际问题。
实验源代码
// 15 实验四:线程的同步.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "15 实验四:线程的同步.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// The one and only application object
CWinApp theApp;
using namespace std;
static HANDLE h1;
static HANDLE hHandle1 = NULL;
void func();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
DWORD dwThreadID1;
DWORD dRes,err;
hHandle1 = CreateSemaphore(NULL, 0, 1, "SemaphoreName1");
if(hHandle1 == NULL) printf("Semaphore Create Fail\n");
else printf("Semaphore Create Success\n");
hHandle1 = OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,
NULL,
"SemaphoreName1");
if(hHandle1 == NULL) printf("Semaphore Open Fail\n");
else printf("Semaphore Open Success\n");
h1 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func,
(LPVOID)NULL,
0,&dwThreadID1);
if(h1==NULL) printf("Thread1 create Fail\n");
else printf("Thread1 create Success\n");
dRes = WaitForSingleObject(hHandle1,INFINITE);
err = GetLastError();
printf("WaitForSingleObject err =%d\n", err);
if(dRes == WAIT_TIMEOUT) printf("TIMEOUT! dRes = %d\n", dRes);
else if(dRes == WAIT_OBJECT_0) printf("WAIT_OBJECT! dRes = %d\n", dRes);
else if(dRes == WAIT_ABANDONED) printf("WAIT_ABANDONED! dRes = %d\n", dRes);
else printf("dRes = %d\n", dRes);
CloseHandle(h1);
CloseHandle(hHandle1);
ExitThread(0);
return nRetCode;
}
void func()
{
BOOL rc;
DWORD err;
printf("Now In Thread\n");
rc = ReleaseSemaphore(hHandle1,1,NULL);
err = GetLastError();
printf("ReleaseSemaphore err = %d\n", err);
if(rc == 0) printf("Semaphore Release Fail\n");
else printf("Semaphore Release Successs! rc = %d\n",rc);
}
实验总结:
- h1是线程句柄,hHandle1是信号量句柄
- CreateSemaphore用于创建一个信号量
- OpenSemaphore打开信号量
- CreateThread创建子线程
- WaitForSingleObject主线程等待子线程结束
- ReleaseSemaphore(hHandle1,1,NULL)是子线程唤醒主线
实验五:线程的互斥
实验环境:计算机一台,内装有VC++、office等软件
实验日期:2024.5.11
实验要求:
1.理解:线程互斥的基本概念。
2.掌握:使用线程互斥API及临界区实现多线程互斥的方法。
实验内容:
1.使用Windows系统提供的系统调用创建与撤销线程。
2.使用Windows系统提供的线程互斥API实现多线程互斥。
3.使用Windows系统提供的线程互斥API解决实际问题。
实验源代码
// 实验五:线程的互斥.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "实验五:线程的互斥.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// The one and only application object
CWinApp theApp;
using namespace std;
static int count = 5;
static HANDLE h1;
static HANDLE h2;
LPCRITICAL_SECTION hCriticalSection;
CRITICAL_SECTION Critical;
void func1();
void func2();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
DWORD dwThreadID1,dwThreadID2;
hCriticalSection = &Critical;
InitializeCriticalSection(hCriticalSection);
h1 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func1,
(LPVOID)NULL,
0,
&dwThreadID1);
if(h1 == NULL) printf("Thread1 create Fail\n");
else printf("Thread1 create Success\n");
h2 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func2,
(LPVOID)NULL,
0,
&dwThreadID2);
if(h2 == NULL) printf("Thread2 create Fail\n");
else printf("Thread2 create Success\n");
Sleep(1000);
CloseHandle(h1);
CloseHandle(h2);
DeleteCriticalSection(hCriticalSection);
ExitThread(0);
return nRetCode;
}
void func2()
{
int r2;
EnterCriticalSection(hCriticalSection);
r2 = count;
_sleep(100);
r2 = r2 + 1;
count = r2;
printf("count in func2 = %d\n", count);
LeaveCriticalSection(hCriticalSection);
}
void func1()
{
int r1;
EnterCriticalSection(hCriticalSection);
r1 = count;
_sleep(500);
r1 = r1 + 1;
count = r1;
printf("count in func1 = %d\n", count);
LeaveCriticalSection(hCriticalSection);
}
实验总结:
- EnterCriticalSection(…)进入临界区
- LeaveCriticalSection(…)退出临界区
- DeleteCriticalSection(…)删除临界区
- InitialCriticalSection(…)初始化临界区
实验六:系统内存使用统计
实验环境:计算机一台,内装有Visual Studio、office等软件
实验日期:2024.6.7
实验要求:
1.了解:Windows内存管理机制。
2.理解:页式存储管理技术,Windows内存管理基本数据结构。
3.掌握:Windows内存管理基本API的使用。
实验内容:
1.使用Windows系统提供的API和数据结构获取系统物理内存和虚拟内存信息。
2.分配及释放虚拟内存。
3.分配及释放物理内存。
4.当物理内存和虚拟内存空间发生变化时,分析产生变化的原因。
工程创建过程
勾选MFC
实验源代码
// 实验六:系统内存使用统计.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "实验六:系统内存使用统计.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
void GetMemSta(){
MEMORYSTATUSEX MemInfo;
MemInfo.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&MemInfo);
printf("当前内存状态是:\n");
printf("总物理内存大小:%dMB\n",MemInfo.ullTotalPhys/(1024*1024));
printf("可用物理内存大小:%dMB\n",MemInfo.ullAvailPhys/(1024*1024));
printf("总页文件大小:%dMB\n",MemInfo.ullTotalPageFile/(1024*1024));
printf("可用页文件大小:%dMB\n",MemInfo.ullAvailPageFile/(1024*1024));
printf("总虚拟内存大小:%dMB\n",MemInfo.ullTotalVirtual/(1024*1024));
printf("可用虚拟内存大小:%dMB\n",MemInfo.ullAvailVirtual/(1024*1024));
printf("内存利用率:%d\n",MemInfo.dwMemoryLoad);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
LPVOID BaseAddr;
GetMemSta();
printf("现在分配300M的虚拟内存和200M的物理内存\n\n");
BaseAddr=VirtualAlloc(NULL, 1024*1024*300,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
if(BaseAddr==NULL) printf("虚拟内存分配失败\n");
char * str = (char*)malloc(1024*1024*300);
GetMemSta();
printf("现在释放300M的虚拟内存和200M的物理内存\n\n");
if(VirtualFree(BaseAddr,0,MEM_RELEASE)==0) printf("释放失败");
free(str);
GetMemSta();
system("PAUSE");
return nRetCode;
}
实验结果: