VC60做的实现线程同步的四种方法的详细操作步骤.docx

上传人:b****6 文档编号:7584411 上传时间:2023-01-25 格式:DOCX 页数:14 大小:112.66KB
下载 相关 举报
VC60做的实现线程同步的四种方法的详细操作步骤.docx_第1页
第1页 / 共14页
VC60做的实现线程同步的四种方法的详细操作步骤.docx_第2页
第2页 / 共14页
VC60做的实现线程同步的四种方法的详细操作步骤.docx_第3页
第3页 / 共14页
VC60做的实现线程同步的四种方法的详细操作步骤.docx_第4页
第4页 / 共14页
VC60做的实现线程同步的四种方法的详细操作步骤.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

VC60做的实现线程同步的四种方法的详细操作步骤.docx

《VC60做的实现线程同步的四种方法的详细操作步骤.docx》由会员分享,可在线阅读,更多相关《VC60做的实现线程同步的四种方法的详细操作步骤.docx(14页珍藏版)》请在冰豆网上搜索。

VC60做的实现线程同步的四种方法的详细操作步骤.docx

VC60做的实现线程同步的四种方法的详细操作步骤

VC6.0做的实现线程同步的四种方法的详细操作步骤

软件作业一:

如何实现线程同步?

(二是一个基于单个文档的MFC程序,参考的是某本书上完整的一个可运行实例,所用代码和课件上几乎相同,应该会更符合老师上课讲的思路)

windows系统提供的4种同步化机制分别为:

临界区

信号量内核对象

事件内核对象

互斥体对象

一:

非MFC下实现线程同步实例

●临界区:

课本P43、44

//CriticalSection.cpp文件

#include

#include

#include

BOOLg_bContinue=TRUE;

intg_nCount1=0;

intg_nCount2=0;

CRITICAL_SECTIONg_cs;//对存在同步问题的代码段使用临界区对象

UINT__stdcallThreadFunc(LPVOID);

intmain(intargc,char*argv[])

{

UINTuId;

HANDLEh[2];

//初始化临界区对象

:

:

InitializeCriticalSection(&g_cs);

h[0]=(HANDLE):

:

_beginthreadex(NULL,0,ThreadFunc,NULL,0,&uId);

h[1]=(HANDLE):

:

_beginthreadex(NULL,0,ThreadFunc,NULL,0,&uId);

//等待1秒后通知两个计数线程结束,关闭句柄

Sleep(1000);

g_bContinue=FALSE;

:

:

WaitForMultipleObjects(2,h,TRUE,INFINITE);

:

:

CloseHandle(h[0]);

:

:

CloseHandle(h[1]);

//删除临界区对象

:

:

DeleteCriticalSection(&g_cs);

printf("g_nCount1=%d\n",g_nCount1);

printf("g_nCount2=%d\n",g_nCount2);

return0;

}

UINT__stdcallThreadFunc(LPVOID)

{

while(g_bContinue)

{

:

:

EnterCriticalSection(&g_cs);

g_nCount1++;

g_nCount2++;

:

:

LeaveCriticalSection(&g_cs);

}

return0;

}

●事件内核对象:

课本P46

//EventDemo.cpp文件

#include

#include

#include

HANDLEg_hEvent;

UINT__stdcallChildFunc(LPVOID);

intmain(intargc,char*argv[])

{

HANDLEhChildThread;

UINTuId;

//创建一个自动重置的(auto-resetevents),未受信的(nonsignaled)事件内核对象

g_hEvent=:

:

CreateEvent(NULL,FALSE,FALSE,NULL);

hChildThread=(HANDLE):

:

_beginthreadex(NULL,0,ChildFunc,NULL,0,&uId);

//通知子线程开始工作

printf("PleaseinputachartotelltheChildThreadtowork:

\n");

getchar();

:

:

SetEvent(g_hEvent);

//等待子线程完成工作,释放资源

:

:

WaitForSingleObject(hChildThread,INFINITE);

printf("Alltheworkhasbeenfinished.\n");

:

:

CloseHandle(hChildThread);

:

:

CloseHandle(g_hEvent);

return0;

}

UINT__stdcallChildFunc(LPVOID)

{

:

:

WaitForSingleObject(g_hEvent,INFINITE);

printf("Childthreadisworking......\n");

:

:

Sleep(5*1000);//暂停5秒,模拟真正的工作

return0;

}

●设定优先级实现三个线程的同步(参见课本P38)

///////////////////////////////////////////////////////////////

//PriorityDemo.cpp文件

#include

#include

HANDLEhMutex=NULL;

charg_cArray[10];

DWORDWINAPIThreadProc1(LPVOIDlpParam)

{

WaitForSingleObject(hMutex,INFINITE);

for(inti=0;i<10;i++)

{

g_cArray[i]='a';

printf("ThreadProc1NormalThreadisrunning\n");

printf("g_cArray[%d]=%c\n",i,g_cArray[i]);

Sleep(1000);//sleep

(1)约为15ms

}

ReleaseMutex(hMutex);

return0;

}

DWORDWINAPIThreadProc2(LPVOIDlpParam)

{

WaitForSingleObject(hMutex,INFINITE);

for(inti=0;i<10;i++)

{

g_cArray[10-i-1]='b';

printf("ThreadProc2LowestThreadisrunning\n");

printf("g_cArray[%d]=%c\n",10-i-1,g_cArray[10-i-1]);

Sleep(1000);

}

ReleaseMutex(hMutex);

return0;

}

DWORDWINAPIThreadProc3(LPVOIDlpParam)

{

WaitForSingleObject(hMutex,INFINITE);

for(inti=0;i<10;i++)

{

g_cArray[i]='c';

printf("ThreadProc3IdleThreadisrunning\n");

printf("g_cArray[%d]=%c\n",i,g_cArray[i]);

Sleep(1000);

}

ReleaseMutex(hMutex);

return0;

}

intmain(intargc,char*argv[])

{

DWORDdwThreadID;

HANDLEh[3];

//创建一个优先级为Normal的线程

h[0]=:

:

CreateThread(NULL,0,ThreadProc1,NULL,

0,&dwThreadID);

//创建一个优先级为Lowest的线程

h[1]=:

:

CreateThread(NULL,0,ThreadProc2,NULL,

CREATE_SUSPENDED,&dwThreadID);

:

:

SetThreadPriority(h[1],THREAD_PRIORITY_LOWEST);

:

:

ResumeThread(h[1]);

//创建一个优先级为Idle的线程

h[2]=:

:

CreateThread(NULL,0,ThreadProc3,NULL,

CREATE_SUSPENDED,&dwThreadID);

:

:

SetThreadPriority(h[2],THREAD_PRIORITY_IDLE);

:

:

ResumeThread(h[2]);

//等待两个线程内核对象都变成受信状态

:

:

WaitForMultipleObjects(

3,

h,

TRUE,

INFINITE);

:

:

CloseHandle(h[0]);

:

:

CloseHandle(h[1]);

:

:

CloseHandle(h[2]);

return0;

}

二:

在MFC下实现线程同步实例(含四种方法)

这是一个基于单个文档的MFC程序(参考的是某本书上完整的一个实例,所用代码和课件上几乎相同)

操作步骤:

1、新建“MFCAPPWIZARD(EXE)”,选择文件路径,输入文件名

2、选择应用程序类型为“单个文档”

3、添加“线程同步的四种方法”的各菜单项,并在类向导的视类中添加各菜单消息函数

ID号

标题

消息函数

IDC_SYN_CRITICALSECTION

临界区

OnSynCriticalsection

IDC_SYN_EVENT

事件内核对象

OnSynEvent

IDC_SYN_MUTEX

互斥内核对象

OnSynMutex

IDC_SYN_SEMAPHORE

信号量内核对象

OnSynSemaphore

添加菜单消息响应函数的方法为:

在MFCClassWizard(类向导)中的CMyView视图下选中要添加消息响应函数的菜单的ID号,单击右侧的Message中双击COMMAND,跳出函数名,单击OK即可

4、在“实现线程同步的四种方法View.cpp”文件开头添加头文件#include"afxmt.h"

5、用“临界区”实现线程同步,在“实现线程同步的四种方法View.cpp”文件中添加相应代码

1)编写线程函数

charcArray[10];//共享资源

CCriticalSectioncriticalSection;//MFC临界区类对象

//临界区线程函数

UINTThreadCriticalFunc1(LPVOIDparam)

{

//进入临界区

criticalSection.Lock();

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[i]='a';

Sleep

(1);

}

//离开临界区

criticalSection.Unlock();

return0;

}

UINTThreadCriticalFunc2(LPVOIDparam)

{

//进入临界区

criticalSection.Lock();

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[10-i-1]='b';

Sleep

(1);

}

//离开临界区

criticalSection.Unlock();

return0;

}

2)在类视图中选择OnSynCriticalsection(),添加代码

voidCMyView:

:

OnSynCriticalsection()//临界区

{

//TODO:

Addyourcommandhandlercodehere

//TODO:

Addyourcommandhandlercodehere

//启动线程

AfxBeginThread(ThreadCriticalFunc1,NULL);

AfxBeginThread(ThreadCriticalFunc2,NULL);

//等待计算完毕

Sleep(300);

//报告计算结果

CStringsResult=CString(cArray);

AfxMessageBox(sResult);

}

3)运行程序,单击“临界区”

弹出

6、用“事件内核对象”实现线程同步,在“实现线程同步的四种方法View.cpp”文件中添加相应代码

1)编写线程函数

//事件内核对象

CEventevent;

UINTThreadEventFunc1(LPVOIDparam)

{

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[i]='a';

Sleep

(1);

}

//设置事件置位

event.SetEvent();

return0;

}

UINTThreadEventFunc2(LPVOIDparam)

{

//等待事件

event.Lock();

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[10-i-1]='b';

Sleep

(1);

}

return0;

}

2)在类视图中选择OnSynEvent(),添加代码

voidCMyView:

:

OnSynEvent()//事件内核对象

{

//TODO:

Addyourcommandhandlercodehere

//TODO:

Addyourcommandhandlercodehere

//启动线程

AfxBeginThread(ThreadEventFunc1,NULL);

AfxBeginThread(ThreadEventFunc2,NULL);

//等待计算完毕

Sleep(300);

//报告计算结果

CStringsResult=CString(cArray);

AfxMessageBox(sResult);

}

3)运行程序,单击“事件内核对象”,弹出

7、用“互斥内核对象”实现线程同步,在“实现线程同步的四种方法View.cpp”文件中添加相应代码

1)编写线程函数

//互斥

CMutexmutex(FALSE,NULL);//互斥类对象

UINTThreadMutexFunc1(LPVOIDparam)

{

mutex.Lock();//等待互斥对象通知

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[i]='a';

Sleep

(1);

}

mutex.Unlock();//释放互斥对象

return0;

}

UINTThreadMutexFunc2(LPVOIDparam)

{

mutex.Lock();//等待互斥对象通知

//对共享资源进行写入操作

for(inti=0;i<10;i++)

{

cArray[10-i-1]='b';

Sleep

(1);

}

mutex.Unlock();//释放互斥对象

return0;

}

2)在类视图中选择OnSynMutex(),添加代码

voidCMyView:

:

OnSynMutex()//互斥内核对象

{

//TODO:

Addyourcommandhandlercodehere

//TODO:

Addyourcommandhandlercodehere

//启动线程

AfxBeginThread(ThreadMutexFunc1,NULL);

AfxBeginThread(ThreadMutexFunc2,NULL);

//等待计算完毕

Sleep(300);

//报告计算结果

CStringsResult=CString(cArray);

AfxMessageBox(sResult);

}

3)运行程序,单击“互斥内核对象”,弹出

8、用“信号量内核对象”实现线程同步,在“实现线程同步的四种方法View.cpp”文件中添加相应代码(这个最符合当时老师布置的作业的要求)

1)编写线程函数

//信号量

CSemaphoresemaphore(2,2);//信号量类对象

UINTThreadSemaphoreFunc1(LPVOIDparam)

{

semaphore.Lock();//试图进入信号量关口

AfxMessageBox("线程一正在执行!

");//线程任务处理

semaphore.Unlock();//释放信号量计数

return0;

}

UINTThreadSemaphoreFunc2(LPVOIDparam)

{

semaphore.Lock();//试图进入信号量关口

AfxMessageBox("线程二正在执行!

");//线程任务处理

semaphore.Unlock();//释放信号量计数

return0;

}

UINTThreadSemaphoreFunc3(LPVOIDparam)

{

semaphore.Lock();//试图进入信号量关口

AfxMessageBox("线程三正在执行!

");//线程任务处理

semaphore.Unlock();//释放信号量计数

return0;

}

2)在类视图中选择OnSynSemaphore(),添加代码

voidCMyView:

:

OnSynSemaphore()//信号量内核对象

{

//TODO:

Addyourcommandhandlercodehere

//TODO:

Addyourcommandhandlercodehere

//启动线程

AfxBeginThread(ThreadSemaphoreFunc1,NULL);

AfxBeginThread(ThreadSemaphoreFunc2,NULL);

AfxBeginThread(ThreadSemaphoreFunc3,NULL);

}

3)运行程序,单击“信号量内核对象”,弹出

单击其中一个对话框的“确定”,弹出

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

当前位置:首页 > 高等教育 > 工学

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

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