操作系统实验

实验一:Windows API函数

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法。

二:实验的工程目标

  1. 熟悉Windows API函数文档的结构、风格;掌握Windows API的调用方法。
  2. 仔细阅读API函数的文档,确保缓冲区大小参数的正确有效。必要时对返回值进行检查。
  3. 编写代码获得当前用户名(GetUserName)、系统目录(GetSystemDirectory)、Windows所在目录(GetWindowsDirectory)、环境变量PATH的值等信息(ExpandEnvironmentStrings)。
  4. 选作:编写代码获得操作系统的版本信息(GetVersionEx)。

三:实验代码

#include <cstdio>
#include <windows.h>
#include <Lmcons.h>

int main() {
    char computer_name_buffer[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD computer_name_buffer_size = MAX_COMPUTERNAME_LENGTH + 1;
    GetComputerNameA(computer_name_buffer, &computer_name_buffer_size);
    printf("ComputerName:%s\n", computer_name_buffer);
    
    char user_name_buffer[UNLEN + 1];
    DWORD user_name_buffer_size = UNLEN + 1;
    
    GetUserNameA(user_name_buffer, &user_name_buffer_size);
    printf("UserName:%s\n", user_name_buffer);
    
    char system_directory_buffer[1000];
    GetSystemDirectoryA(system_directory_buffer, 1000);
    printf("SystemDirectory:%s\n", system_directory_buffer);
    
    char windows_directory_buffer[MAX_PATH];
    GetWindowsDirectoryA(windows_directory_buffer, MAX_PATH);
    printf("WindowsDirectory%s\n", windows_directory_buffer);
    
    const char *environment_string = "%path%";
    char environment_string_expanded[10000];
    ExpandEnvironmentStringsA(environment_string, environment_string_expanded, 10000);
    printf("EnvironmentPath:%s\n", environment_string_expanded);
    
    OSVERSIONINFO version;
    ZeroMemory(&version, sizeof(OSVERSIONINFO));
    version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&version);
    printf("Version:%d.%d %s\n", version.dwMajorVersion, version.dwMinorVersion, version.szCSDVersion);
    
    return 0;
}

四:实验结果

![Windows API实验结果](https://img-blog.csdnimg.cn/img_convert/63ca61b607ce2075078f1b77f3825696.png#clientId=u0e8940c2-faf6-4&from=paste&height=401&id=u9fa32c6b&originHeight=401&originWidth=983&originalType=binary&ratio=1&rotation=0&showTitle=true&size=78227&status=done&style=none&taskId=ub40bd4c0-70ee-41ae-844e-b82a84eb72a&title=Windows API实验结果&width=983 “Windows API实验结果”)

实验二:线程与互斥

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法

二:实验的工程目标

  1. 改写money的代码,用“高级锁”即信号量代替“低级锁”,并感受二者的性能差异。如果可以,请用clock函数测量这种差异(选作)。还可以比较使用多线程与单线程的性能差异(选作)。
  2. 提示:此处信号量代表什么资源?对全局变量money的访问权就是一种资源,这种资源的数量为1。

三:实验代码

#include <windows.h>
#include <iostream>
#include <ctime>

using namespace std;

int money = 0;
CRITICAL_SECTION lock;

DWORD WINAPI dad(LPVOID) {
    EnterCriticalSection(&lock);
    for (int i = 0; i < 100000; i++) {
        money++;
    }
    LeaveCriticalSection(&lock);
    return 0;
}

DWORD WINAPI mom(LPVOID) {
    EnterCriticalSection(&lock);
    for (int i = 0; i < 100000; i++) {
        money++;
    }
    LeaveCriticalSection(&lock);
    return 0;
}

DWORD WINAPI oth(LPVOID) {
    EnterCriticalSection(&lock);
    for (int i = 0; i < 100000; i++) {
        money++;
    }
    LeaveCriticalSection(&lock);
    return 0;
}

int main() {
    clock_t start, middle, finish;
    double Times;
    start = clock();

    HANDLE thread_dad;
    HANDLE thread_mom;
    HANDLE thread_oth;

    InitializeCriticalSection(&lock);

    thread_dad = CreateThread(nullptr, 0, dad, nullptr, 0, nullptr);
    thread_mom = CreateThread(nullptr, 0, mom, nullptr, 0, nullptr);
    thread_oth = CreateThread(nullptr, 0, oth, nullptr, 0, nullptr);

    middle = clock();
    Times = (double) (middle - start) / CLOCKS_PER_SEC;
    cout << "低级锁运行时间(秒): " << Times << endl;

    WaitForSingleObject(thread_dad, INFINITE);
    WaitForSingleObject(thread_mom, INFINITE);
    WaitForSingleObject(thread_oth, INFINITE);

    DeleteCriticalSection(&lock);

    finish = clock();
    Times = (double) (finish - middle) / CLOCKS_PER_SEC;
    cout << "高级锁运行时间(秒): " << Times << endl;

    return 0;
}

四:实验结果

线程与互斥运行结果

实验三:页置换模拟

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法。

二:实验的工程目标

  1. 给定一个页面访问的轨迹,程序模拟先进先出置换算法下操作系统的行为。
  2. 参考FIFO置换算法的模拟程序,实现LRU算法的模拟程序。
  3. 选作:加上一列显示调出页;修复程序的bug(提示:FIFOQueue数组元素为0时,是表示没东西)
  4. 考虑下述页面走向:1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6,当内存块数量分别为3时,试问FIFO、LRU置换算法的缺页次数各是多少?

三:实验代码

#include <cstdio>

const int MemCapacity = 3;
int FIFOQueue[MemCapacity] = {0};
int exit_page = 0;

int pageInMainMem(int page) {
    for (int i = 0; i < MemCapacity; i++) {
        if (FIFOQueue[i] == page)
            return i;
    }
    return -1;
}

void foldPage(int page) {
    for (int i = MemCapacity - 1; i > 0; i--)
        FIFOQueue[i] = FIFOQueue[i - 1];
    FIFOQueue[0] = page;
}

int main() {
    int pageFootprints[] = {1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6};
    int pageNum = sizeof pageFootprints / sizeof pageFootprints[0];


    int RequestCount = 0;
    bool request;

    printf("时刻\t访问页面\t主存状态\t缺页中断\t调入页\t调出页\n");
    for (int i = 0; i < pageNum; i++) {
        printf("%3d\t %2d\t     ", i, pageFootprints[i]);
        request = false;
        if (pageInMainMem(pageFootprints[i]) == -1) {

            if (FIFOQueue[MemCapacity - 1] != 0) {
                exit_page = FIFOQueue[MemCapacity - 1];
            }
            foldPage(pageFootprints[i]);
            RequestCount++;
            request = true;
        }
        for (int j: FIFOQueue)
            printf("%2d ", j);

        if (request) {
            printf("\t\t+");
            printf("\t     %d", pageFootprints[i]);
            if (exit_page != 0) {
                printf("\t    %d", exit_page);
            }
        }

        printf("\n");

    }

    printf("缺页中断次数 = %d\n", RequestCount);
    printf("缺页率 = %d/%d = %.2f%%\n", RequestCount, pageNum, (float) RequestCount / (float) pageNum * 100);

    return 0;
}

四:实验结果

页置换模拟

实验四:创建进程

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法。

二:实验的工程目标

使用CreateProcess函数创建新的进程。程序中创建新的进程,新进程执行记事本的可执行文件打开记事本,主进程休眠,等待记事本进程结束。用户关闭记事本后,WinMain函数中的主进程关闭进程句柄后结束。

三:实验代码

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    TCHAR sCommandLine[1000];
    BOOL ret;
    DWORD dwExitCode;
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {sizeof(si)};
    //得到Windows目录
    GetWindowsDirectory(sCommandLine, MAX_PATH);
    //启动"记事本"程序的命令行
    strcat(sCommandLine, "\\notepad.exe");
    // 启动"记事本"作为子进程
    ret = CreateProcess(nullptr, sCommandLine, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);
    if (ret) {
        CloseHandle(pi.hThread);
        //关闭子进程的主线程句柄
        WaitForSingleObject(pi.hProcess, INFINITE);
        //等待子进程的退出
        GetExitCodeProcess(pi.hProcess, &dwExitCode);
        //获取子进程的退出码
        CloseHandle(pi.hProcess);
        //关闭子进程句柄
    }
    return 0;
}

四:实验结果

创建进程实验结果

实验五:进程中启动计算器子程序

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法。

二:实验的工程目标

用程序实现启动一个新的进程,并在进程中启动计算器应用程序(calc.exe)。

三:实验代码

#include<windows.h>
#include<cstdio>

int main() {
    char path[10] = "calc.exe";
    DWORD dwExitCode;
    PROCESS_INFORMATION pi;
    DWORD ret;
    STARTUPINFO si = {sizeof(si)};
    ret = CreateProcess(nullptr, path, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);
    if (ret) {
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hThread);
        GetExitCodeProcess(pi.hProcess, &dwExitCode);
        CloseHandle(pi.hProcess);
    }
    printf("\n进程结束,退出码是 %ld\n", ret);
    return 0;
}

四:实验结果

进程中启动计算器子程序

实验六:建立线程(一个线程,主线程不休眠)

一:实验要求

  1. 请在代码中你认为重要处加上注释。
  2. 除了粘贴代码外,请用专门的文字对程序的设计做简要介绍。
  3. 如果你在做这个程序的过程中遇到了困难、走了弯路,请一一列出,并说明导致问题的原因,以及你最终的解决办法。

二:实验的工程目标

程序演示使用函数_beginthreadex启动线程。

三:实验代码

#include <cstdio>
#include <windows.h>
#include <process.h>

unsigned int WINAPI Fun(LPVOID lpParamter) {
    while (true) {
        printf("---Fun display!\n");
        Sleep(500);//休眠0.5s
    }
    return 0;
}

int main() {
    HANDLE hThread;
    hThread = (HANDLE) _beginthreadex(nullptr, 0, Fun, nullptr, 0, nullptr);//创建线程,执行Fun函数
    while (true) {
        printf("main display!\n");
        Sleep(500);//休眠0.5s
    }
    CloseHandle(hThread);//关闭句柄
    return 0;
}

四:实验结果

建立线程实验结果

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北溪入江流

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值