进程管理
实验提示
PCB结构通常包括以下信息:进程名,进程优先数,轮转时间片,进程所占用的CPU时间,进程的状态,当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删。
例:实验运行结果
********************************************
* 进程演示系统 *
********************************************
1.创建新的进程 2.查看运行进程
3.换出某个进程 4.杀死运行进程
5.进程之间通信 6.退出系统
********************************************
请选择(1~6)
然后根据你选择的不同,出现不同的结果。
老师只说是用windows系统编程技术实现上述操作,第三个换出我还做不出来,还有杀死进程那个也有些问题,有人可以帮帮忙么,我把我现在做的发出来,望大虾帮忙下!!!
#include<stdio.h> //包含头文件
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<iostream.h>
#include <iostream>
#include <windows.h>
static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide" ;
// 要使用的文件名
static LPCTSTR g_szFileName = "w2kdg.Fileobj.file.data.txt" ;
// 创建传递过来的进程的克隆过程并赋于其ID值
void StartClone(int nCloneID)
{
// 提取用于当前可执行文件的文件名
TCHAR szFilename[MAX_PATH] ;
:: GetModuleFileName(NULL, szFilename, MAX_PATH) ;
// 格式化用于子进程的命令行并通知其EXE文件名和克隆ID
TCHAR szCmdLine[MAX_PATH];
:: sprintf(szCmdLine,"\"%s\" d%",szFilename,nCloneID);
// 用于子进程的STARTUPINFO结构
STARTUPINFO si;
:: ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ;
si.cb = sizeof(si) ; // 必须是本结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOL bCreateOK=::CreateProcess(
szFilename, // 产生这个EXE的应用程序的名称
szCmdLine, // 告诉其行为像一个子进程的标志
NULL, // 缺省的进程安全性
NULL, // 缺省的线程安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, // 使用新的控制台
NULL, // 新的环境
NULL, // 当前目录
&si, // 启动信息
&pi) ; // 返回的进程信息
// 对子进程释放引用
if (bCreateOK)
{
:: CloseHandle(pi.hProcess) ;
:: CloseHandle(pi.hThread) ;
}
}
/*获取进程信息*/
void GetProcessInfo()
{
// 提取这个进程的ID号
DWORD dwIdThis=:: GetCurrentProcessId();
// 获得这一进程和报告所需的版本,也可以发送0以便指明这一进程
DWORD dwVerReq=:: GetProcessVersion(dwIdThis);
WORD wMajorReq=(WORD)(dwVerReq>16) ;
WORD wMinorReq=(WORD)(dwVerReq & 0xffff) ;
std :: cout << "Process ID: "<< dwIdThis
<<", requires OS: " << wMajorReq
<< wMinorReq << std :: endl ;
// 设置版本信息的数据结构,以便保存操作系统的版本信息
OSVERSIONINFOEX osvix;
:: ZeroMemory(&osvix, sizeof(osvix) ) ;
osvix.dwOSVersionInfoSize=sizeof(osvix) ;
// 提取版本信息和报告
:: GetVersionEx(reinterpret_cast < LPOSVERSIONINFO > (&osvix)) ;
std :: cout << "Running on OS:" << osvix.dwMajorVersion <<"."
<< osvix.dwMinorVersion << std :: endl;
// 如果是NTS(Windows 2000) 系统,则提高其优先权
if (osvix.dwPlatformId==VER_PLATFORM_WIN32_NT && osvix.dwMajorVersion >= 5)
{
// 改变优先级
:: SetPriorityClass(
:: GetCurrentProcess() , // 利用这一进程
HIGH_PRIORITY_CLASS); // 改变为high
// 报告给用户
std::cout << "Task Manager should now indicate this "
"process is high priority."<< std :: endl;
}
getchar();
}
/*用子进程杀掉父进程*/
// 创建当前进程的克隆进程的简单方法
void StartClone()
{
// 提取当前可执行文件的文件名
TCHAR szFilename[MAX_PATH] ;
:: GetModuleFileName(NULL, szFilename, MAX_PATH) ;
// 格式化用于子进程的命令行,指明它是一个EXE文件和子进程
TCHAR szCmdLine[MAX_PATH] ;
:: sprintf(szCmdLine, "\"%s\"child" , szFilename) ;
// 子进程的启动信息结构
STARTUPINFO si;
:: ZeroMemory(reinterpret_cast <void*>(&si),sizeof(si)) ;
si.cb = sizeof(si) ; // 应当是此结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 用同样的可执行文件名和命令行创建进程,并指明它是一个子进程
BOOL bCreateOK=::CreateProcess(
szFilename, // 产生的应用程序的名称 (本EXE文件)
szCmdLine, // 告诉我们这是一个子进程的标志
NULL, // 用于进程的缺省的安全性
NULL, // 用于线程的缺省安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, //创建新窗口
NULL, // 新环境
NULL, // 当前目录
&si, // 启动信息结构
&pi ) ; // 返回的进程信息
// 释放指向子进程的引用
if (bCreateOK)
{
:: CloseHandle(pi.hProcess) ;
:: CloseHandle(pi.hThread) ;
}
}
void Parent()
{
// 创建“自杀”互斥程序体
HANDLE hMutexSuicide=:: CreateMutex(
NULL, // 缺省的安全性
TRUE, // 最初拥有的
g_szMutexName) ; // 为其命名
if (hMutexSuicide != NULL)
{
// 创建子进程
std :: cout << "Creating the child process." << std :: endl;
:: StartClone() ;
// 暂停
:: Sleep(5000) ;
// 指令子进程“杀”掉自身
std :: cout << "Telling the child process to quit. "<< std :: endl;
:: ReleaseMutex(hMutexSuicide) ;
// 消除句柄
:: CloseHandle(hMutexSuicide) ;
}
}
void Child()
{
// 打开“自杀”互斥体
HANDLE hMutexSuicide = :: OpenMutex(
SYNCHRONIZE, // 打开用于同步
FALSE, // 不需要向下传递
g_szMutexName) ; // 名称
if (hMutexSuicide != NULL)
{
// 报告我们正在等待指令
std :: cout <<"Child waiting for suicide instructions. " << std :: endl;
:: WaitForSingleObject(hMutexSuicide, INFINITE) ;
// 准备好终止,清除句柄
std :: cout << "Child quiting." << std :: endl;
:: CloseHandle(hMutexSuicide) ;
}
}
// 在数据文件中读取当前数据的简单线程时将传递来的该数据增加,并写回数据文件中
static DWORD WINAPI ThreadProc (LPVOID lpParam)
{
// 将参数翻译为长整数
LONG nAdd = reinterpret_cast <LONG> (lpParam) ;
// 建立完全的指定文件名
TCHAR szFullName [MAX_PATH] ;
:: GetTempPath(MAX_PATH, szFullName) ;
:: strcat(szFullName, g_szFileName) ;
// 打开文件对象
HANDLE hFile = :: CreateFile(
szFullName, // 文件的完全名称
GENERIC_READ | GENERIC_WRITE, // 具有所有的访问权
FILE_SHARE_READ, // 允许其他线程读取
NULL, // 缺省的安全性
OPEN_ALWAYS, // 创建或打开文件
FILE_ATTRIBUTE_NORMAL, // 普通文件
NULL) ; // 无模板文件
if (hFile != INVALID_HANDLE_VALUE)
{
// 读取当前数据
LONG nValue(0) ;
DWORD dwXfer(0) ;
:: ReadFile(
hFile, // 要读取的文件
reinterpret_cast <LPVOID> (&nValue) , // 缓冲区
sizeof(nValue) , // 缓冲区容量
&dwXfer, // 读取的字节数
NULL) ; // 无重叠I/O
if (dwXfer == sizeof(nValue) )
{
// 显示当前数据
std :: cout << "read: " << nValue << std :: endl;
}
// 增加数值
nValue += nAdd;
// 写回永久存储介质
:: SetFilePointer(hFile, 0, NULL, FILE_BEGIN) ;
:: WriteFile(
hFile, // 要写入的文件
reinterpret_cast <LPCVOID> (&nValue) , // 数据
sizeof(nValue), // 缓冲区容量
&dwXfer, // 写入的字节数
NULL) ; // 无重叠I/O
if (dwXfer == sizeof(nValue) )
{
std :: cout << "write: " << nValue << std :: endl;
}
// 清除文件
:: CloseHandle(hFile) ;
hFile = INVALID_HANDLE_VALUE;
}
return(0) ;
}
/*进程通信*/
void ProcessComunication()
{
// 创建100个线程从文件中进行读写
for (int nTotal = 10; nTotal > 0; --nTotal)
{
// 启动线程
HANDLE hThread = :: CreateThread(
NULL, // 缺省的安全性
0, // 缺省的堆栈
ThreadProc, // 线程函数
reinterpret_cast <LPVOID> (1) , // 增量
0, // 无特殊的创建标志
NULL) ; // 忽略线程id
// 等待线程完成
:: WaitForSingleObject(hThread, INFINITE) ;
// 释放指向线程的句柄
:: CloseHandle(hThread) ;
hThread = INVALID_HANDLE_VALUE;
}
getchar();
}
void menu()
{
cout<<"\n"<<endl;
cout<<"\n"<<endl;
cout<<"\t\t*********************************************"<<endl;
cout<<"\t\t* 进程演示系统 *"<<endl;
cout<<"\t\t*********************************************"<<endl;
cout<<"\n"<<endl;
cout<<"\t\t <a> 创建新的进程 <b> 查看运行的进程\n\n"<<endl;
cout<<"\t\t <c> 换出某个进程 <d> 杀死某个进程\n\n"<<endl;
cout<<"\t\t <e> 进程间的通信 <f> 退出系统\n\n"<<endl;
cout<<"\t\t*********************************************"<<endl;
cout<<"\n"<<endl;
cout<<"\n请选择(a[A]~f[F]):"<<endl;
cout<<"\n"<<endl;
}
void main(int argc, char* argv[] )
{
char ch;
while(1)
{
menu(); //用户界面提示
ch=getch();
switch(ch)
{
case 'a':
case 'A':
{
int nClone(0) ;
if (argc > 1)
{
// 从第二个参数中提取克隆ID
:: sscanf(argv[1] , "%d" , &nClone) ;
}
// 显示进程位置
std :: cout << "Process ID:" << :: GetCurrentProcessId()
<< ", Clone ID:" << nClone
<<std :: endl;
// 检查是否有创建子进程的需要
const int c_nCloneMax=25;
if (nClone < c_nCloneMax)
{
// 发送新进程的命令行和克隆号
StartClone(++nClone) ;
}
// 在终止之前暂停一下 (l/2秒)
:: Sleep(500) ;
}
break;
case 'b':
case 'B':
GetProcessInfo();
break;
case 'c':
case 'C':
break;
case 'd':
case 'D':
{
// 决定其行为是父进程还是子进程
if (argc>1 && :: strcmp(argv[1] , "child" )== 0)
{
Child() ;
}
else
{
Parent() ;
}
getchar();
}
break;
case 'e':
case 'E':
ProcessComunication();
break;
case 'f': //退出程序
case 'F':
exit(0);
default:
cout<<"选择有误,按任意键重新输入"<<endl;
getch();
break;
}
}
}