实验项目名称: Windows进程管理
一、实验目的
1、学习windows系统提供的线程创建、线程撤销、线程同步等系统调用;
2、利用C++实现线程创建、线程撤销、线程同步程序;
3、完成思考、设计与练习。
二、实验内容
1、写一个windows控制台程序(需要MFC),创建子线程,显示Hello, This is a Thread. 然后撤销该线程。
2、向线程对应的函数传递参数,如字符串“hello world!”,在线程中显示。
3、如何创建3个线程A, B, C,并建立先后序执行关系A→B→C。
4、完成父线程和子线程的同步。父线程创建子线程后进入阻塞状态,子线程运行完毕后再唤醒。
三、实验原理
相关系统调用:
线程创建: CreateThread()
线程撤销: ExitThread()
线程终止: ExitThread(0)
线程挂起: Sleep()
关闭句柄: CloseHandle()
等待对象 WaitForSingleObject(), WaitForMultipleObjects();
信号量对象 CreateSemaphore(), OpenSemaphore(), ReleaseSemaphore();
HANDLE WINAPI CreateSemaphore(
In_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
In LONG lInitialCount,
In LONG lMaximumCount,
In_opt LPCTSTR lpName
);
四、实验代码
(1)创建线程
#include “stdafx.h”
#include “OS-TEST.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
void ThreadName1();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
static HANDLE hHandle1=NULL;
DWORD dwThreadID1;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}
}
else
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: GetModuleHandle 失败\n"));
nRetCode = 1;
}
hHandle1=CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) ThreadName1,
(LPVOID) NULL,
0,
&dwThreadID1);
Sleep(5000);
CloseHandle(hHandle1);
ExitThread(0);
//getchar();
return nRetCode;
}
void ThreadName1()
{
printf(“Hello, This is a Thread.”);
}
(2)撤销线程
#include “stdafx.h”
#include “OS-TEST.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
void ThreadName1();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
static HANDLE hHandle1=NULL;
DWORD dwThreadID1;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T(“错误: MFC 初始化失败\n”));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}
}
else
{
_tprintf(_T(“错误: GetModuleHandle 失败\n”));
nRetCode = 1;
}
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(“hello world!”);
}
(3)线同步
#include “stdafx.h”
#include “afxwinappex.h”
#include “afxdialogex.h”
#include “os实验一.h”
#include “MainFrm.h”
#include “os实验一Doc.h”
#include “os实验一View.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
void ThreadName1();
void ThreadName2();
void ThreadName3();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
static HANDLE hHandle1=NULL;
static HANDLE hHandle2=NULL;
static HANDLE hHandle3=NULL;
DWORD dwThreadID1;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T(“错误: MFC 初始化失败\n”));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}
}
else
{
_tprintf(_T(“错误: GetModuleHandle 失败\n”));
nRetCode = 1;
}
hHandle1=CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) ThreadName1,
(LPVOID) NULL,
0,
&dwThreadID1);
hHandle2=CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) ThreadName2,
(LPVOID) NULL,
0,
&dwThreadID1);
hHandle3=CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) ThreadName3,
(LPVOID) NULL,
0,
&dwThreadID1);
Sleep(50000);
CloseHandle(hHandle1);
CloseHandle(hHandle2);
CloseHandle(hHandle3);
ExitThread(0);
//getchar();
return nRetCode;
}
void ThreadName1()
{
printf(“hello world!\n”);
}
void ThreadName2()
{
printf(“How do Pikachu walk? \n”);
}
void ThreadName3()
{
printf(“Pika Ping, Pika Pong!\n”);
}
using namespace std;
void ThreadName1();
static HANDLE h1;
static HANDLE h2;
static HANDLE h3;
static HANDLE hHandle1=NULL;
void func();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
DWORD dwThreadID1;
DWORD dwThreadID2;
DWORD dwThreadID3;
DWORD dRes,err;
//LPCWSTR lPCWSTR=“SemaphoreName1”;
//hHandle1=CreateSemaphore(NULL,0,1, NULL); // CREATE A SEMAPHORE
hHandle1=CreateSemaphore(NULL,0,1, L"SemaphoreName1"); // CREATE A SEMAPHORE
if (hHandle1==NULL) printf("Semaphore create ERR!\n");
else printf("Semaphore create success!\n");
hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,
NULL,
L"SemaphoreName1"); //OPEN SEMAPHORE
if (hHandle1==NULL) printf("Semaphore open ERR!\n");
else printf("Semaphore open success!\n");
h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func,
(LPVOID)NULL,
0,
&dwThreadID1); //CREATE CHILD THREAD
if (h1==NULL) printf("Thread1 create ERR!\n");
else printf("Thread1 create success!\n");
dRes=WaitForSingleObject(hHandle1,INFINITE); //WAIT FOR CHILD THREAD END
err=GetLastError();
printf("Wait for single object ERR=%d\n",err);
if(dRes==WAIT_TIMEOUT)printf("TIMEOUT OF 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);
Sleep(10000);
CloseHandle(h1);
//==================================================================================
h2=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func,
(LPVOID)NULL,
0,
&dwThreadID2); //CREATE CHILD THREAD
if (h2==NULL) printf("Thread2 create ERR!\n");
else printf("Thread2 create success!\n");
dRes=WaitForSingleObject(hHandle1,INFINITE); //WAIT FOR CHILD THREAD END
err=GetLastError();
printf("Wait for single object ERR=%d\n",err);
if(dRes==WAIT_TIMEOUT)printf("TIMEOUT OF 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);
Sleep(10000);
CloseHandle(h2);
h3=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func,
(LPVOID)NULL,
0,
&dwThreadID3); //CREATE CHILD THREAD
if (h3==NULL) printf("Thread3 create ERR!\n");
else printf("Thread3 create success!\n");
dRes=WaitForSingleObject(hHandle1,INFINITE); //WAIT FOR CHILD THREAD END
err=GetLastError();
printf("Wait for single object ERR=%d\n",err);
if(dRes==WAIT_TIMEOUT)printf("TIMEOUT OF 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);
Sleep(10000);
CloseHandle(h3);
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("Release Semaphore err=%d\n",err);
if(rc==0) printf("Semaphore Release Fail.\n");
else printf("Semaphore Release Success. rc=%d\n",rc);
}