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,如需转载请自行联系原作者

相关文章
|
7月前
|
Kubernetes Linux Go
使用 Uber automaxprocs 正确设置 Go 程序线程数
`automaxprocs` 包就是专门用来解决此问题的,并且用法非常简单,只需要使用匿名导入的方式 `import _ "go.uber.org/automaxprocs"` 一行代码即可搞定。
323 78
|
Java 开发者
如何通过易语言多线程提升程序响应速度
如何通过易语言多线程提升程序响应速度
600 62
|
安全 Java
线程安全的艺术:确保并发程序的正确性
在多线程环境中,确保线程安全是编程中的一个核心挑战。线程安全问题可能导致数据不一致、程序崩溃甚至安全漏洞。本文将分享如何确保线程安全,探讨不同的技术策略和最佳实践。
197 6
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
835 7
|
消息中间件 存储 安全
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
270 5
|
Java 开发者
如何通过易语言多线程提升程序响应速度?
如何通过易语言多线程提升程序响应速度?
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
497 6
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
295 0
C++ 多线程之线程管理函数
|
监控 Java API