012244信安1401杨紫淇 计算机操作系统22Word下载.docx

上传人:b****6 文档编号:18344949 上传时间:2022-12-15 格式:DOCX 页数:16 大小:172.89KB
下载 相关 举报
012244信安1401杨紫淇 计算机操作系统22Word下载.docx_第1页
第1页 / 共16页
012244信安1401杨紫淇 计算机操作系统22Word下载.docx_第2页
第2页 / 共16页
012244信安1401杨紫淇 计算机操作系统22Word下载.docx_第3页
第3页 / 共16页
012244信安1401杨紫淇 计算机操作系统22Word下载.docx_第4页
第4页 / 共16页
012244信安1401杨紫淇 计算机操作系统22Word下载.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

012244信安1401杨紫淇 计算机操作系统22Word下载.docx

《012244信安1401杨紫淇 计算机操作系统22Word下载.docx》由会员分享,可在线阅读,更多相关《012244信安1401杨紫淇 计算机操作系统22Word下载.docx(16页珍藏版)》请在冰豆网上搜索。

012244信安1401杨紫淇 计算机操作系统22Word下载.docx

行完毕后唤醒主线程。

3.实验要求:

能正确使用等待对象、WaitForSingleObject()或WaitForMultipleObject(0及信号量对

象CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()等系统调用,进一步

理解线程的同步。

4.实验准备:

相关API函数介绍

5.试验指导:

具体操作过程同本章实验一,在MicrosoftvisualC++6.0环境下建立一个MFC支持的控

制台文件,编写C程序,在程序中使用CreateSemaphore(NULL,0,1,”SemaphoreName1”)

创建一个名为“SemaphoreName1”的信号量,信号量的初始值为0,之后使用OpenSemaphore

(SYNCHRONIZE|SEMAPHORE_MODIFY_STARTE,NULL,”SemaphoreName1)打开该信号量,这

里访问标志使用“SYNCHRONIZE|SEMAPHORE_MODIFY_STARTE”,以便之后可以使用

WaitForSingleObject()等待该信号量及使用ReleaseSemaphore()释放该信号量,然后创

建一个子线程,主线程创建子线程后调用WaitForSingleObject(hHandle1,INFINITE),这里

等待时间设置为INFINITE表示一直等待下去,直到该信号量被唤醒为止。

子线程结束,调用

ReleaseSemaphore(hHandle1,1,NULL)释放信号量,使信号量的值加1。

6.实验过程:

7.实验总结:

实验完成了主、子线程的同步,主线程创建子线程后,主线程塞,让子线程先执行,等

子线程执行完后,由子线程唤醒子线程。

主子线程运行情况如图:

主、子线程的运行情况

说明:

1.实验名称、实验目的、实验内容、实验要求由教师确定,实验前由教师事先填好,然后作为实验报告模版供学生使用;

2.实验准备由学生在实验或上机之前填写,教师应该在实验前检查;

3.实验过程由学生记录实验的过程,包括操作过程、遇到哪些问题以及如何解决等;

4.实验总结由学生在实验后填写,总结本次实验的收获、未解决的问题以及体会和建议等;

5.源程序、代码、具体语句等,若表格空间不足时可作为附录另外附页。

源程序:

//Thread.cpp:

Definestheentrypointfortheconsoleapplication.

#include"

stdafx.h"

Thread.h"

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

//Theoneandonlyapplicationobject

CWinApptheApp;

usingnamespacestd;

voidThreadName()

{

printf("

ThreadisRunning!

\n"

);

}

staticHANDLEhHandle1=NULL;

DWORDThreadID1;

int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])

intnRetCode=0;

hHandle1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,

0,

(LPTHREAD_START_ROUTINE)ThreadName,

(LPVOID)NULL,

&

ThreadID1);

Sleep(5000);

CloseHandle(hHandle1);

ExitThread(0);

returnnRetCode;

//initializeMFCandprintanderroronfailure

if(!

AfxWinInit(:

:

GetModuleHandle(NULL),NULL,:

GetCommandLine(),0))

{

//TODO:

changeerrorcodetosuityourneeds

cerr<

<

_T("

FatalError:

MFCinitializationfailed"

)<

endl;

nRetCode=1;

}

else

codeyourapplication'

sbehaviorhere.

CStringstrHello;

strHello.LoadString(IDS_HELLO);

cout<

(LPCTSTR)strHello<

returnnRetCode;

voidThreaName1()

{printf("

!

【注意】:

文件的路径一定是能够匹配的。

【基础知识】:

(1)lpThreadAttributes:

为线程指定安全属性.为NULL时,线程得到一个默认的安全描述符.

(2)dwStackSize:

线程堆栈的大小.其值为0时,其大小与调用该线程的线程堆栈大小相同.

(3)lpStartAddress:

指定线程要执行的函数.

(4)lpparameter:

函数中要传递的参数.

(5)dwCreationFlags:

指定线程创建后所处的状态.若为CRRATE_SUSPENDED,表示创建后出

于挂起状态,用ResumeThread()激活线程才可以执行.若该值为0,表示线程创建后立即执行.

(6)lpThreadId:

用一个32位的变量接受系统返回的线程标识符.若该值设为NULL,系统不

返回线程标识符.

2.2线程的同步

//Semaphore.cpp:

#include"

Semaphore.h"

staticHANDLEh1;

//线程句柄

//信号量句柄

voidfunc();

intnRetCode=0;

DWORDdwThreadID1;

DWORDdRes,err;

hHandle1=CreateSemaphore(NULL,0,1,"

SemaphoreName1"

//创建一个信号量

if(hHandle1==NULL)printf("

SemaphoreCreate!

elseprintf("

SemaphoreCreateSuccess!

hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,

NULL,

"

//打开信号量

SemaphoreOpenFail!

SemaphoreOpenSuccess!

h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,

(LPTHREAD_START_ROUTINE)func,

0,&

dwThreadID1);

//创建子进程

if(h1==NULL)printf("

Thread1createFail!

Thread1createSuccess!

dRes=WaitForSingleObject(hHandle1,INFINITE);

//主线程等待子线程结束

err=GetLastError();

WaitForSingleObjecterr=%d\n"

err);

if(dRes==WAIT_TIMEOUT)printf("

TIMEOUT!

dRes=%d\n"

dRes);

elseif(dRes==WAIT_OBJECT_0)printf("

WAIT_OBJECT!

elseif(dRes==WAIT_ABANDONED)

WAIT_ABANDONED!

Dres=%d\n"

dRes=%d\n"

CloseHandle(h1);

voidfunc()

BOOLrc;

DWORDerr;

NowInThread!

rc=ReleaseSemaphore(hHandle1,1,NULL);

err=GetLastError();

ReleaseSemaphoreerr=%d\n"

if(rc==0)printf("

SemaphoreReleaseFail!

SemaphoreReleaseSuccess!

rc=%d\n"

rc);

运行情况:

等待对象(waitfuctions)函数包括等待一个对象(WaitForSingleObject())和等待多对

象(WaitForMultipleObject())两个API函数。

等待一个对象

WaitForMultipleObject()用于等待一个对象。

他等待的对象可以为以下对象之一。

Changenotification:

变化通知。

Consoleinput:

控制台输入。

Events:

事件。

Job:

作业。

Mutex:

互斥信号量。

Process:

进程。

Semaphore:

计数信号量。

Thread:

线程。

Waitabletimer:

定时器。

原型:

DWORDWaitForSingleObject(

HANDLEhHandle,//对象句柄

DWORDdwMilliseconds//等待时间

);

参数说明:

hHandle:

等待对象的对象句柄。

该对象句柄必须为SYNCHRONIZE访问。

dwMilliseconds:

等待时间,单位为ms。

若改值为0,函数在测试对象的状态后立即返

回,若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒,如表2‐1所示。

返回值:

如果返回成功,其返回值说明是何种事件导致函数返回。

表2‐1函数描述

访问描述

WAIT_ABANDONED等待对象的是一个互斥(mutex)对象,该互斥对象没有被拥

有它的线程释放,他被设置为不能被唤醒

WAIT_OBJECT_0指定对象被唤醒

WAIT_TIMEOUT超时

用法举例:

StaiticHANDLEhHandle1=NULL;

DWORDdRes;

dRes=WaitForSingleObject(hHandle1,10);

//等待对象的句柄为hHandle,等待时间为

1000ms

等待多个对象

WaitForMultipleObject()在指定时间内等待多个对象,他等待的对象与

WaitForSingleObject()相同。

DWORDWaitForMultipleObject(

DWORDnCount,//句柄数组中的句柄数

XONSTHANDLE*lpHandles,//指向对象句柄数组的指针

BOOLfWaitAll,//等待类型

参数说明:

nCount:

由指针*lpHandles指定的句柄数组中的句柄数,最大数是

MAXIMUM_WAIT_OBJECTS。

*lpHandles:

指向对象句柄数组的指针。

fWAitAll:

等待类型。

若存为true,当由lpHandles数组指定的所有对象被唤醒时函数返

回;

若为FALSE,当由lpHandles数组制定的某一个对象被唤醒时函数返回,且有返回值说

明事由哪个对象引起的函数返回。

dwMilliseconds:

等待时间。

单位为ms。

若该值为0,函数测试对象的状态后立即返回;

若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒。

如果成功返回,其返回值说明是何种事件导致函数返回。

各参数的描述如表2‐2所示。

表2‐2各参数描述

WAIT_OBJECT_0to(WAIT_OBJECT若bWaitAll为TRUE,返回值说明所有被等待的对象均

被唤醒;

_0+nCount‐1)bWaitAll为FALSE。

返回值减去WAIT_OBJECT_0说明

lpHandles数组下标指定的对象满足等待条件。

如果调用时多个对象同时被唤醒,则取多个

对象中最小的那个数组下标

WAIT_ABANDONED_0to若bWaitAll为TRUE,返回值说明所有被等带的对象

均被唤醒,并且(WIAT_ABANDONED‐0+NcOUNT‐1)至少有一个对象是没有约束的互斥

对象;

若bWaitAll

为FALSE,返回值减去WAIT_ABANDONED_0说明lpHandles数组下标指定的没有约束的互斥

对象满足等待条件

WAIT_TIMNEOUT超时且参数bWaitAll指定的条件不能满足

信号量对象(semaphore)

信号量对象(semaphore)包括创建信号量(CreateSemaphore())打开信号量

OpenSemaphore()及增加信号量的值(ReleaseSemaphore())API函数。

创建信号量

CreateSemaphore()用于创建一个信号量。

HANDLECreateSemaphore(

LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,//安全属性

LONGlInitialCount,//信号量对象初始值

LONGliMaximumCount,//信号量最大值

LPCTSTRlpName//信号量名

lpSemaphoreAttributes:

指定安全属性,为null是,信号量得到一个默认的安全描述符。

lInitialCount:

指定信号量对象的初始值。

该值必须大于等于0,小于等于

lMaximumCount。

当其值大于0是,信号量被唤醒。

当该函数释放了一个等待该信号量的

线程时,lInitialCount值减1,当调用函数ReleaseSemaphore()时,按其指定的数量加一个值。

lMaximumCount:

指出该信号量的最大值,该值必须大于0.

lpName:

给出该信号量的名字。

信号量创建成功,将返回该型号量的句柄。

如果给出的信号量名是系统已经存在的信号

量,将返回这个已经存在的信号量的句柄。

如果失败,系统返回null,还可以调用函数

GEtLastError()查询失败的原因。

StaticHANDLEhHandle1=null;

//创建一个信号量,其初值为0,最大值为5,信号量的名字为“SemphoreName1”

hHnadle1=CreateSemaphore(NULL,0,5,"SemphoreName1");

打开信号量

OpenSemaphore()用于打开一个信号量。

HANDLEOpenSemaphore(

DWORDdwDesidedAccess,//访问标志

BOOLbInheritHandle,//继承标志

LPCTSTRlpNme//信号量名

(1).dwDesiredAccess:

指出打开后要对信号量进行何种访问,如表2-3所示。

表2‐3访问状态

SEMAPHORE_ALL_ACCESS可以进行任何对信号量的访问

SEMPHORE_MODFIY_STATE可以使用ReleaseSemaphore()修改信号量的值,使信号量

的值成为可用状态

SYNCHRONIZE使用等待函数(waitfunctions),等待信号量成为可用状态

(2).bInheritHandle:

指出返回的的信号量句柄是否可以继承。

(3).lpName:

给出信号量的名字

信号量打开成功,将返回信号量的句柄;

如果失败,系统返回null,可以调用函数

GetLastError()查询失败的原因。

//打开一个名为”SemphoreName1”的信号量,之后可使用ReleaseSemaphore()函

数增加信号量的值hHandle1=OpenSemaphore(SEMAPHORE_MOFDIFY_START,NULL,”

SemphoreName1”);

3.增加信号量的值

ReleaseSemaphore()用于增加信号量的值。

BOOLReleaseSemaphore(

HANDLEhSemaphore,//信号量对象句柄

LONGlReleaseCount,//信号量要增加数值

LPLONGlpPreiousCount//信号量要增加数值地址

(1).hSemaphore:

创建或打开信号量时给出的信号量对象句柄。

WindowsNT中建议

使用SEMAPHORE_MODIFY_STARTE访问属性打开该信号量。

(2).lReleaseCount:

信号量要增加数值。

该值必须大于0。

如果增加该值后大于信号

创建时给出的lMaximumCount值,则增加操作失效,函数返回FALSE。

(3).lpPreiousCount:

接收信号量的一个32位的一个变量。

若不需要接受该值,可

以指定为null。

如果成功,将返回一个非0值;

如果失败,系统返回一个0,可以调用一个GetLastError

()查询失败的原因。

StaticHANDLEhHandle1=NULL;

BOOLrc;

rc=ReleaseSemaphore(hHandle1,1,NULL);

//给信号量的值加1;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1