操作系统:进程的控制和通信(Windows2000)

简介: 操作系统:进程的控制和通信(Windows2000)


进程的控制和通信(Windows2000)

一、实验目的

通过对Windows 2000编程,进一步熟悉操作系统的基本概念,并能较好地理解Windows 2000的结构。

通过创建进程,观察进程的运行和终止程序以及调试操作,进一步熟悉操作系统的进程概念,理解Windows 2000进程的生命周期。

二、实验要求与内容、过程与结果

  1. 参照例2-2,编写一个程序,利用进程句柄来获得当前运行进程的优先级。
#include<Windows.h>
#include<iostream>
using namespace std;
int main()
{
    //从当前进程中提取句柄
    HANDLE hProcessThis=GetCurrentProcess();  
    //请求内核提供该进程所属的优先权类
    DWORD dwPriority=GetPriorityClass(hProcessThis);
    //发出消息,为用户描述该类
    printf("current process priority:");
    switch(dwPriority)
    {
    case HIGH_PRIORITY_CLASS:
        printf("High\n");
      break;
    case NORMAL_PRIORITY_CLASS:
        printf("Normal\n");
        break;
    case IDLE_PRIORITY_CLASS:
        printf("Idle\n");
        break;
    //case REAL_TIME_ PRIORITY_CLASS:
    //  printf("Realtime\n");
    //    break;
    default:
        printf("<unknow>\n");
        break;
    }
}

程序分析

本代码主要通过Windows API函数GetPriorityClass获取当前进程的优先级类别,然后通过switch语句输出对应的优先级名称。

在Windows操作系统下,为了更好地管理和调度进程,操作系统将所有的进程分成了不同的优先级类别,这些类别按照优先级从高到低依次为:

  1. REALTIME_PRIORITY_CLASS:实时优先级类,只有操作系统内核可以使用,在执行实时任务时使用。
  2. HIGH_PRIORITY_CLASS:高优先级类,通常用于非常紧急且时间敏感的任务,如音视频编解码、实时数据传输等。
  3. NORMAL_PRIORITY_CLASS:普通优先级类,大多数进程都属于此类别,系统分配的默认类别。
  4. IDLE_PRIORITY_CLASS:空闲优先级类,用于低优先级的任务,不会影响其他进程的执行,通常用于节能和减少电脑噪音等场景。

在本代码中,首先调用GetPriorityClass函数获取当前进程的优先级类别,返回的是DWORD类型的优先级常量,然后通过switch语句将其转化为对应的字符串输出。

需要注意的是,在代码中我们注释掉了REALTIME_PRIORITY_CLASS这个优先级类别,因为该优先级类别只有操作系统内核才能使用,一般用户进程无法使用,否则可能会对系统稳定性造成危害。实际上,该优先级类别在一些特定场景下还是会被用到的,如视频监控、游戏引擎等。

总之,通过获取和了解进程的优先级类别,我们可以更好地控制进程的执行顺序和优先级,从而提升系统性能和响应速度。

  1. 运行例2-3,记录运行结果(不少于5个进程的信息),并描述该程序的功能。

程序功能:利用进程句柄获得进程详细信息, 应用程序显示当前运行进程名字以及在核心态下占用时间的百分比。

  1. 运行例2-4,记录运行结果,并描述该程序的功能。

程序功能:通过当前进程,创建相同的子进程。

4.参照例2-5,编写一个程序,给出运行进程的操作系统的版本号。

5.用命令行的方式运行2次例2-6(每次命令行参数不同:命令行中是否包含“child”参数),记录运行结果,并描述该程序的功能。

功能:创建子进程,描述了进程间的互斥与同步。该程序开始时时先进入parent()函数,然后parent()函数会创建自杀互斥体和一个子进程,并暂停5秒后杀死自己,这时子进程会进入child()函数并打开自杀互斥体,等待父进程杀掉自身后终止。

6.参照例2-6,编写一个程序,通过创建进程来执行一个命令列表(命令列表中有3个应用程序的程序名,这些程序运行一段时间后被中止退出),并输出每个进程(这3个应用程序)的执行时间。

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include<ctime>
#pragma warning(disable: 4996)
using namespace std;
static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide";
//创建当前进程的克隆进程的简单方法
void StartClone(int num)
{
  TCHAR szFilename[MAX_PATH];
  //获得当前可执行文件的文件名
  GetModuleFileName(NULL, szFilename, MAX_PATH);
  //格式化子进程的命令行,指明是一个EXE文件和子进程
  TCHAR szCmdLine[MAX_PATH];
  sprintf(szCmdLine, "%s  %d", szFilename,num);
  //子进程的启动信息结构
  STARTUPINFO si;
  ZeroMemory(reinterpret_cast <void *> (&si), sizeof(si));
  si.cb = sizeof(si);
  PROCESS_INFORMATION p;  //说明一个返回的子进程信息结构
  //利用同样的可执行文件名和命令行创建进程,并指明是一个子进程
  BOOL bCreateOK = CreateProcess(
    szFilename,    //产生的应用程序的名称
    szCmdLine,    //指定创建一个子进程的符号标识
    NULL,       //默认的进程安全性
    NULL,     //默认的线程安全性
    FALSE,       //不继承句柄
    CREATE_NEW_PROCESS_GROUP, //创建新窗口,使输出更直观
    NULL,       //新环境
    NULL,       //当前目录
    &si,        //启动信息结构
    &p);        //返回的进程信息
  //关闭子进程
  if (bCreateOK)
  {
    CloseHandle(p.hProcess);
    CloseHandle(p.hThread);
  }
}
void Parent()
{
  //创建“自杀”互斥体
  HANDLE hMutexSuicide = CreateMutex(
    NULL,    //默认的安全性
    TRUE,    //创建者是互斥体的最初拥有者
    g_szMutexName);    //为互斥体命名
  if (hMutexSuicide != NULL)
  {
    StartClone(1);    //创建两个子进程
    StartClone(2);
    Sleep(5000);    //暂停(5秒)
    ReleaseMutex(hMutexSuicide);  //通知子进程”杀”掉自身
    CloseHandle(hMutexSuicide);   //消除互斥体句柄
  }
  printf("name: parent time: %f s\n", (double)clock() / CLOCKS_PER_SEC);
  getchar();
}
void Child(char * argv[])
{   //打开“自杀”互斥体
  HANDLE hMutexSuicide = OpenMutex(
    SYNCHRONIZE,    //打开用于同步
    FALSE,        //不需要向下传递
    g_szMutexName);  //互斥体名称
  if (hMutexSuicide != NULL)
  {
    WaitForSingleObject(hMutexSuicide, INFINITE);
    //等待子进程释放互斥体
    //准备好终止,清除句柄
    CloseHandle(hMutexSuicide);
  }
  printf("name: child%s time: %f s\n", argv[1], (double)clock() / CLOCKS_PER_SEC);
}
int main(int argc, char * argv[])
{
  //决定其行为是父进程还是子进程
  if (argc > 1)
  {
    Child(argv);
  }
  else
  {
    Parent();
  }
  return 0;
}

程序分析

本代码主要演示了如何通过创建“克隆”进程的方式实现父进程通知子进程自杀的功能。

该代码的核心是利用Windows API函数CreateProcess创建进程,并利用命令行参数的方式来区分父进程和子进程。父进程会创建两个子进程,然后暂停5秒,并通过创建一个“自杀”互斥体来通知子进程自杀。子进程则会打开这个互斥体并等待通知,收到通知后即可终止自身。

具体实现过程如下:

首先创建了一个名为“w2kdg.ProcTerm.mutex.Suicide”的互斥体,用于父进程通知子进程自杀。

然后在主函数中通过判断命令行参数的个数,来决定当前进程是父进程还是子进程。如果命令行参数个数大于1,则说明当前进程是子进程;否则,就是父进程。可以通过命令行参数的方式把当前进程的角色传递给子进程。

在父进程中,调用StartClone函数创建两个子进程,同时暂停5秒钟。在创建子进程的时候,使用了CREATE_NEW_PROCESS_GROUP参数,这样可以在屏幕上创建两个独立的命令行窗口,使输出更直观。

然后,父进程获得了“自杀”互斥体的句柄,并释放了这个互斥体,通知子进程自杀。父进程还输出了当前运行时间,再通过getchar来等待用户输入,以保证在结束进程之前不会立即关闭命令行窗口。

在子进程中,首先打开“自杀”互斥体,并等待父进程通知。一旦收到通知,子进程就会终止自身,释放句柄并退出。

需要注意的是,这种通过创建“克隆”进程的方式来通信和控制进程的方法并不是一种很好的做法。因为这种方式存在许多潜在的问题,比如进程之间的同步和通信机制都需要手动实现,并且容易导致死锁和进程的长时间挂起等问题。在实际的开发中,建议使用更为高级和稳定的通信和同步机制,如线程、信号量和管道等。

目录
相关文章
|
1天前
|
消息中间件 Linux 调度
深入理解操作系统的进程管理
【9月更文挑战第34天】本文将深入浅出地介绍操作系统中的进程管理,从进程的概念开始,逐步展开到进程调度、进程同步与通信等核心内容。我们将通过简单的代码示例,帮助读者更好地理解进程管理的原理和实践。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供有价值的参考。
23 12
|
1天前
|
算法 调度 UED
深入理解操作系统的进程调度策略
【9月更文挑战第34天】在计算机科学中,操作系统是硬件与用户之间的桥梁,它管理着系统资源和提供各项服务。本文旨在通过浅显易懂的语言和实际代码示例,揭示操作系统的核心机制之一——进程调度策略。我们将探讨进程调度的目的、常见的调度算法以及它们如何影响系统性能和用户体验。无论你是编程新手还是资深开发者,这篇文章都将帮助你更好地理解并运用这些知识来优化你的应用程序和系统配置。
23 11
|
3天前
|
算法 调度 UED
探索操作系统的心脏:进程调度算法
【9月更文挑战第32天】在数字世界的每一次心跳中,都隐藏着一个不为人知的英雄——进程调度算法。它默默地在后台运作,确保我们的命令得到快速响应,应用程序平稳运行。本文将带你走进操作系统的核心,一探进程调度的奥秘,并通过代码示例揭示其背后的智慧。准备好跟随我一起深入这趟技术之旅了吗?让我们开始吧!
|
5天前
|
算法 Linux 调度
深入理解操作系统的进程调度
【9月更文挑战第30天】本文将带你进入操作系统的核心—进程调度。我们将探讨其工作原理,分析几种常见的调度算法,并通过实际代码示例来揭示这些理论是如何在真实系统中实现的。无论你是初学者还是有经验的开发者,这篇文章都能帮助你更好地理解操作系统的这一关键组成部分。
|
5天前
|
消息中间件 算法 调度
探索操作系统核心:进程管理与调度策略
【9月更文挑战第30天】在数字化时代的心脏,操作系统扮演着至关重要的角色。本文将深入探讨操作系统的基石之一——进程管理,以及如何通过调度策略优化系统性能。我们将从进程的基本概念出发,逐步解析进程状态、进程控制和进程间通信等关键要素。同时,我们会探讨几种常见的进程调度算法,并分析它们的优缺点。最后,文章将展示一个简单的代码示例,以加深对理论部分的理解和应用。
|
1天前
|
算法 Linux 调度
操作系统的心脏:深入理解进程调度
本文将深入探讨操作系统中最核心的概念之一——进程调度。通过简明扼要的语言和具体实例,帮助读者理解进程调度的基本原理、算法及其在现代操作系统中的应用。我们将从简单的轮转调度到复杂的多级反馈队列调度,一步步揭开这个复杂系统的面纱。
12 4
|
1天前
|
算法 调度
深入理解操作系统:进程管理与调度
【9月更文挑战第34天】操作系统是计算机系统的核心,负责管理和控制计算机硬件和软件资源。本文将探讨操作系统中的一个重要概念——进程管理与调度。我们将了解进程的概念、进程状态以及进程调度算法。通过学习这些知识,我们可以更好地理解操作系统的工作原理,为进一步学习和研究打下基础。
|
6天前
|
算法 调度 UED
探索操作系统的心脏:进程管理与调度
【9月更文挑战第29天】在数字世界的海洋中,操作系统是支撑软件与硬件和谐共舞的桥梁。本文将深入探讨操作系统的核心功能—进程管理及其调度机制,揭示它们是如何影响计算机性能和用户体验的。通过浅显易懂的语言和生动的比喻,我们将一起遨游在进程的生命周期、调度算法以及优先级等概念之间,旨在为读者呈现一个清晰的操作系统内部运作图景。
17 6
|
5天前
|
算法 调度 开发者
深入理解操作系统之进程管理与调度
【9月更文挑战第30天】本文旨在通过浅显易懂的语言和具体代码示例,带领读者探索操作系统中进程管理的奥秘。我们将从进程的生命周期出发,逐步解析进程调度的核心概念,并通过实例展示如何实现简单的进程调度算法。无论你是初学者还是有一定基础的开发者,都能在这篇文章中找到有价值的信息,帮助你更好地理解和掌握进程管理与调度的知识。
15 4
|
6天前
|
算法 调度 UED
深入理解操作系统:进程管理与调度策略
【9月更文挑战第29天】在数字世界的心脏,操作系统悄无声息地跳动着,它的健康直接关系到整个计算生态系统的活力。本文将带领读者穿梭于操作系统的微观世界,探索进程管理的奥秘和调度策略的智慧。我们将从进程的基本概念出发,逐步深入到进程的生命周期管理,最后探讨不同的进程调度算法及其对系统性能的影响。通过深入浅出的方式,让读者能够更好地理解并掌握操作系统中进程管理的核心知识。
下一篇
无影云桌面