Windows Mobile使用Native C++开发多线程程序

简介:

简介

上一篇文章 Windows Mobile使用.NET Compact Framework开发多线程程序 讲述了如何使用.NET Compact Framework进行多线程程序的开发,这篇讲述Native C++开发多线程程序的方法。

 

实现

环境

mutilthreading-native-cpp-1

mutilthreading-native-cpp-2

Environment: Visual Studio 2008 + Native C++ + WTL 8.1 + Windows Mobile 5.0 R2 professional (VS 2008 built-in) + ARMV4I

 

类定义 Class Definition

 

public:
void SendRequest();
void HandleRequest();

private:
HANDLE volatile mHandlerEvent;
HANDLE mHandlerThreadHnd;
DWORD mHandlerThreadId;

HANDLE mRequesterThreadHnd;
DWORD mRequesterThreadId;

MessageQueue mMessageQueue;
CRITICAL_SECTION mLook;

bool volatile mStarted;

private:
void UpdateMessageList(const CString& msg);
void StartThreading();
void StopThreading();

mHandlerEvent is the event to wake up handler thread.

mHandlerThreadHnd is the handler thread’s handle.

mHandlerThreadId is the handler thread’s Id

mMessageQueue is the shared resource. I use STL queue to encapsulate it.

mLook is a CRITICAL_SECTION object and is used to lock the shared resource.

mHandlerEvent  用于唤醒处理线程的事件。

mHandlerThreadHnd  线程句柄。

mHandlerThreadId 线程ID。

mMessageQueue STL的queue,共享资源,用于线程间分享数据。

mLook 是 CRITICAL_SECTION 对象,用于线程间的加锁。

 

Start two threads

//    Handler thread methods
DWORD WINAPI HanlderThreadProc(void *param)
{
if (param)
{
try
{
CThreadingDemoView* view = (CThreadingDemoView*)param;
view->HandleRequest();
}
catch(...)
{
}
}
return 0;
}

// Requester thread methods
DWORD WINAPI RequesterThreadProc(void *param)
{
if (param)
{
try
{
CThreadingDemoView* view = (CThreadingDemoView*)param;
view->SendRequest();
}
catch(...)
{
}
}
return 0;
}
void CThreadingDemoView::StartThreading()
{
if(!mStarted)
{
UpdateMessageList("Start threading...");
mStarted = true;

InitializeCriticalSection(&mLook);

mHandlerEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // manual reset, initial state is nonsignaled

mHandlerThreadHnd = CreateThread(NULL, 0, &HanlderThreadProc, this, CREATE_SUSPENDED, &mHandlerThreadId);
if (mHandlerThreadHnd)
{
SetThreadPriority(mHandlerThreadHnd, THREAD_PRIORITY_NORMAL);
ResumeThread(mHandlerThreadHnd);
}

mRequesterThreadHnd = CreateThread(NULL, 0, &RequesterThreadProc, this, CREATE_SUSPENDED, &mRequesterThreadId);
if (mRequesterThreadHnd)
{
SetThreadPriority(mRequesterThreadHnd, THREAD_PRIORITY_NORMAL);
ResumeThread(mRequesterThreadHnd);
}
}
}

Initialise some data members such mLook and mHandlerEvent. And start the requester thread and handler thread. I would like to pass through the class pointer to the global functions and use member function of the class to run the thread.

初始化各个变量。然后启动两个线程,启动线程的时候把本身对象指针传递到静态函数,这样处理的时候还是对象的方法来处理。 新线程会调用成员函数HandleRequest()和SendRequest()来运行,把所有的逻辑还是封装在同一个类里面。

 

Requester thread

void CThreadingDemoView::SendRequest()
{
int i = 0;
while(mStarted)
{
if(i > 100)
{
i = 0;
}

Message msg(i, "CPP");
EnterCriticalSection(&mLook);
mMessageQueue.push(msg);
LeaveCriticalSection(&mLook);

// Signal the event
SetEvent(mHandlerEvent);

CString s;
s.Format(_T("%8.8x - %d - %s"), ::GetCurrentThreadId(), msg.mID, msg.mMessageBody);
UpdateMessageList(s);

//sleep 500 milliseconds
Sleep(500);
++i;
}
//printf("Requester thread terminated.\n");
}

Create an object of Message and put it into the queue (mMessageQueue). Use EnterCriticalSection() and LeaveCriticalSection() to lock the shared resource and then wake the handler thread.

简单化处理,发送请求线程支持生成一个请求对象,然后加锁放到共享queue中,然后通过事件唤醒处理线程。

 

Handler thread

void CThreadingDemoView::HandleRequest()
{
while (mStarted)
{
// Wait for the incomming request
WaitForSingleObject(mHandlerEvent, INFINITE); //INFINITE
ResetEvent(mHandlerEvent);

//Use temp queue to decrease the lock duration.
MessageQueue tempMessageQueue;
EnterCriticalSection(&mLook);
while(!mMessageQueue.empty() && mStarted)
{
tempMessageQueue.push(mMessageQueue.front());
mMessageQueue.pop();
}
LeaveCriticalSection(&mLook);

//procoss the request
while(!tempMessageQueue.empty())
{
CString s;
s.Format(_T("%8.8x - %d - %s"), ::GetCurrentThreadId(), tempMessageQueue.front().mID, tempMessageQueue.front().mMessageBody);
UpdateMessageList(s);
tempMessageQueue.pop();
}

}
//printf("Handler thread terminated.\n");
}

The handler thread will sleep until get the event (mHandlerEvent). Put all the requests to temporary queue and release lock. Display the thread id and message information when process the request.

处理线程一直sleep直到给mHandlerEvent事件所唤醒,在现实处理中,处理对象可能时间比较长,所以为了减少锁的时间,把请求放到临时queue中,然后再处理不用锁的临时queue。

 

Stop Threads

void CThreadingDemoView::StopThreading()
{
if(mStarted)
{
UpdateMessageList("Stop threading...");
mStarted = false;

// Signal the event
SetEvent(mHandlerEvent);

// Wait for the Thread to Die
WaitForSingleObject(mHandlerThreadHnd, INFINITE);
CloseHandle(mHandlerThreadHnd);

WaitForSingleObject(mRequesterThreadHnd, INFINITE);
CloseHandle(mRequesterThreadHnd);

DeleteCriticalSection(&mLook);
CloseHandle(mHandlerEvent);

mHandlerEvent = INVALID_HANDLE_VALUE;
mHandlerThreadHnd = NULL;
mHandlerThreadId = 0;
mRequesterThreadHnd = NULL;
mRequesterThreadId = 0;
}
}

发信号停止线程,清理各种对象。

 

一个Native C++版本的多线程同步以及通信程序完成了,可以对比 Windows Mobile使用.NET Compact Framework开发多线程程序 来看,非常欢迎拍板,请多拍拍,无论程序,英文描述等等,好让我不断改进,早日得到offer。

 

源代码 http://files.cnblogs.com/procoder/ThreadingDemo.zip

 

可能是这个月最后一篇博文了,搬家没有宽带。




    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2010/03/11/Multithreading-native-cpp.html,如需转载请自行联系原作者

相关文章
|
9天前
|
IDE 关系型数据库 开发工具
使用Visual Basic进行Windows窗体开发
【4月更文挑战第27天】本文介绍了使用Visual Basic进行Windows窗体(WinForms)开发的步骤,从搭建开发环境到创建、设计用户界面,再到编写事件驱动的代码和数据绑定。Visual Basic结合WinForms提供了一种易学易用的桌面应用开发方案。通过调试、优化、部署和维护,开发者可以构建专业应用程序。随着技术发展,掌握最新UI设计和开发工具对于保持竞争力至关重要。本文为初学者提供了基础指导,鼓励进一步探索和学习。
|
5天前
|
Linux API C++
c++多线程——互斥锁
c++多线程——互斥锁
|
5天前
|
前端开发 Linux iOS开发
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
【4月更文挑战第30天】Flutter扩展至桌面应用开发,允许开发者用同一代码库构建Windows、macOS和Linux应用,提高效率并保持平台一致性。创建桌面应用需指定目标平台,如`flutter create -t windows my_desktop_app`。开发中注意UI适配、性能优化、系统交互及测试部署。UI适配利用布局组件和`MediaQuery`,性能优化借助`PerformanceLogging`、`Isolate`和`compute`。
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
|
7天前
|
编解码 Linux Windows
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
本文档介绍了在Windows环境下如何为FFmpeg集成libopus和libvpx库。首先,详细阐述了安装libopus的步骤,包括下载源码、配置、编译和安装,并更新环境变量。接着,同样详细说明了libvpx的安装过程,注意需启用--enable-pic选项以避免编译错误。最后,介绍了重新配置并编译FFmpeg以启用这两个库,通过`ffmpeg -version`检查是否成功集成。整个过程参照了《FFmpeg开发实战:从零基础到短视频上线》一书的相关章节。
22 0
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
|
8天前
|
编解码 Linux Windows
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
在Windows环境下,为FFmpeg集成音频编解码库,包括libogg、libvorbis和opencore-amr,涉及下载源码、配置、编译和安装步骤。首先,安装libogg,通过配置、make和make install命令完成,并更新PKG_CONFIG_PATH。接着,安装libvorbis,同样配置、编译和安装,并修改pkgconfig文件。之后,安装opencore-amr。最后,重新配置并编译FFmpeg,启用ogg和amr支持,通过ffmpeg -version检查是否成功。整个过程需确保环境变量设置正确,并根据路径添加相应库。
25 1
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
|
4天前
|
编译器 C++
【C++】一文全解四种经典 [ 特殊类 ]的设计
【C++】一文全解四种经典 [ 特殊类 ]的设计
|
5天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-3
c++初阶------类和对象(六大默认构造函数的揭破)
|
5天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-2
c++初阶------类和对象(六大默认构造函数的揭破)
|
5天前
|
存储 编译器 C语言
c++初阶------类和对象(六大默认构造函数的揭破)-1
c++初阶------类和对象(六大默认构造函数的揭破)
|
5天前
|
存储 编译器 C语言
c++初阶-------类和对象-2
c++初阶-------类和对象