资料介绍
Windows CE 进程、线程和内存管理(二)
2006-12-09 17:50:44 来源:嵌入式资讯网
分享到: 二、同步
在多数情况下,线程之间难免要相互通信、相互协调才能完成任务。比如,当有多个线程共同访问同一个资源时,就必须保证一个线程正读取这个资源数据的时候,其它线程不能够修改它。这就需要线程之间相互通信,了解对方的行为。再有当一个线程要准备执行下一个任务之前,它必须等待另一个线程终止才能运行,这也需要彼此相互通信。实际开发过程中,线程间需要同步的情况非常多。Windows CE.NET给我们提供了很多的同步机制,熟练的掌握这些机制并合理运用会使线程之间的同步更合理、更高效。进程间的通信机制在下一篇文章中讲解。
Windows CE.NET具有两种运行模式:用户模式和内核模式。并且允许一个运行于用户模式的应用程序随时切换为内核模式,或切换回来。线程同步的有些解决办法运行在用户模式,有些运行在内核模式。《Windows核心编程》上说从用户模式切换到内核模式再切换回来至少要1000个CPU周期。我查看过CE下API函数SetKMode的源码,这个函数用于在两种模式间切换,改变模式只需修改一些标志,至于需要多少个CPU周期很难确定。但至少可以肯定来回切换是需要一定时间的。所以在选择同步机制上应该优先考虑运行在用户模式的同步解决办法。
1、互锁函数
互锁函数运行在用户模式。它能保证当一个线程访问一个变量时,其它线程无法访问此变量,以确保变量值的唯一性。这种访问方式被称为原子访问。互锁函数及其功能见如下列表:
函数参数和功能
InterlockedIncrement参数为PLONG类型。此函数使一个LONG变量增1
InterlockedDecrement参数为PLONG类型。此函数使一个LONG变量减1
InterlockedExchangeAdd参数1为PLONG类型,参数2为LONG类型。此函数将参数2赋给参数1指向的值
InterlockedExchange参数1为PLONG类型,参数2为LONG类型。此函数将参数2的值赋给参数1指向的值
InterlockedExchangePointer参数为PVOID* 类型,参数2为PVOID类型。此函数功能同上。具体参见帮助
InterlockedCompareExchange参数1为PLONG类型,参数2为LONG类型,参数3为LONG类型。此函数将参数1指向的值与参数3比较,相同则把参数2的值赋给参数1指向的值。不相同则不变
InterlockedCompareExchangePointer参数1为PVOID* 类型,参数2为PVOID类型,参数3为PVOID。此函数功能同上。具体参见帮助
2、临界区
临界区对象运行在用户模式。它能保证在临界区内所有被访问的资源不被其它线程访问,直到当前线程执行完临界区代码。除了API外,MFC也对临界区函数进行了封装。临界区相关函数:
void InitializeCriticalSection ( LPCRITICAL_SECTION );
void EnterCriticalSection ( LPCRITICAL_SECTION );
void LeaveCriticalSection ( LPCRITICAL_SECTION );
void DeleteCriticalSection ( LPCRITICAL_SECTION );
举例如下:
void CriticalSectionExample (void)
{
CRITICAL_SECTION csMyCriticalSection;
InitializeCriticalSection (&csMyCriticalSection); ///初始化临界区变量
__try
{
EnterCriticalSection (&csMyCriticalSection); ///开始保护机制
///此处编写代码
}
__finally ///异常处理,无论是否异常都执行此段代码
{
LeaveCriticalSection (&csMyCriticalSection); ///撤销保护机制
}
}
MFC类使用更简单:
CCriticalSection cs;
cs.Lock();
///编写代码
cs.Unlock();
使用临界区要注意的是避免死锁。当有两个线程,每个线程都有临界区,而且临界区保护的资源有相同的时候,这时就要在编写代码时多加考虑。
3、事件对象
事件对象运行在内核模式。与用户模式不同,内核模式下线程利用等待函数来等待所需要的事件、信号,这个等待过程由操作系统内核来完成,而线程处于睡眠状态,当接收到信号后,内核恢复线程的运行。内核模式的优点是线程在等待过程中并不浪费CPU时间,缺点是从用户模式切换到内核模式需要一定的时间,而且还要切换回来。在讲解事件对象前应该先谈谈等待函数。等待函数有四个。具体参数和功能见下表:
函数参数和功能
WaitForSingleObject参数1为HANDLE类型,参数2为DWORD类型。此函数等待参数1标识的事件,等待时间为参数2的值,单位ms。如果不超时,当事件成为有信号状态时,线程唤醒继续运行。
WaitForMultipleObjects参数1为DWORD类型,参数2为HANDLE * 类型,参数3为BOOL类型,参数4为DWORD类型。此函数等待参数2指向的数组中包含的所有事件。如果不超时,当参数3为FALSE时,只要有一个事件处于有信号状态,函数就返回这个事件的索引。参数3为TRUE时,等待所有事件都处于有信号状态时才返回。
MsgWaitForMultipleObjects参数1为DWORD类型,参数2为LPHANDLE类型,参数3为BOOL类型,参数4为DWORD类型,参数5为DWORD类型。此函数功能上同WaitForMultipleObjects函数相似,只是多了一个唤醒掩码。唤醒掩码都是和消息有关的。此函数不但能够为事件等待,还能为特定的消息等待。其实这个函数就是专为等待消息而定义的。
MsgWaitForMultipleObjectsEx参数1为DWORD类型,参数2为LPHANDLE类型,参数3为DWORD类型,参数4为DWORD类型,参数5为DWORD类型。此函数是MsgWaitForMultipleObjects函数的扩展。将原来函数的参数3除掉,添加参数5为标志。标志有两个值:0或MWMO_INPUTAVAILABLE。
如果一个线程既要执行大量任务同时又要响应用户的按键消息,这两个专用于等待消息的函数将非常有用。
和事件有关的函数有:
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPTSTR lpName);
BOOL SetEvent(HANDLE hEvent );
BOOL PulseEvent(HANDLE hEvent);
BOOL ResetEvent(HANDLE hEvent);
HANDLE OpenEvent(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName );
事件对象是最常用的内核模式同步方法。它包含一个使用计数和两个BOOL变量。其中一个BOOL变量指定这个事件对象是自动重置还是手工重置。另一个BOOL变量指定当前事件对象处于有信号状态还是无信号状态。
函数CreateEvent创建一个事件对象,参数1必须为NULL,参数2指定是否手工重新设置事件对象的状态。如果为FALSE,当等待函数接到信号并返回后此事件对象被自动置为无信号状态。这时等待此事件对象的其它线程就不会被唤醒,因为事件对象已经被置为无信号状态。如果参数2设置为TRUE,当等待函数接到信号并返回后事件对象不会被自动置于无信号状态,其它等待此事件对象的线程都能够被唤醒。用ResetEvent函数可以手工将事件对象置为无信号状态。相反SetEvent函数将事件对象置为有信号状态。PulseEvent函数将事件对象置为有信号状态,然后立即置为无信号状态,在实际开发中这个函数很少使用。OpenEvent函数打开已经创建的事件对象,一般用于不同进程内的线程同步。在调用CreateEvent创建一个事件对象时,传递一个名字给参数4,这样在其它进程中的线程就可以调用OpenEvent函数并指定事件对象的名字,来访问这个事件对象。
2006-12-09 17:50:44 来源:嵌入式资讯网
分享到: 二、同步
在多数情况下,线程之间难免要相互通信、相互协调才能完成任务。比如,当有多个线程共同访问同一个资源时,就必须保证一个线程正读取这个资源数据的时候,其它线程不能够修改它。这就需要线程之间相互通信,了解对方的行为。再有当一个线程要准备执行下一个任务之前,它必须等待另一个线程终止才能运行,这也需要彼此相互通信。实际开发过程中,线程间需要同步的情况非常多。Windows CE.NET给我们提供了很多的同步机制,熟练的掌握这些机制并合理运用会使线程之间的同步更合理、更高效。进程间的通信机制在下一篇文章中讲解。
Windows CE.NET具有两种运行模式:用户模式和内核模式。并且允许一个运行于用户模式的应用程序随时切换为内核模式,或切换回来。线程同步的有些解决办法运行在用户模式,有些运行在内核模式。《Windows核心编程》上说从用户模式切换到内核模式再切换回来至少要1000个CPU周期。我查看过CE下API函数SetKMode的源码,这个函数用于在两种模式间切换,改变模式只需修改一些标志,至于需要多少个CPU周期很难确定。但至少可以肯定来回切换是需要一定时间的。所以在选择同步机制上应该优先考虑运行在用户模式的同步解决办法。
1、互锁函数
互锁函数运行在用户模式。它能保证当一个线程访问一个变量时,其它线程无法访问此变量,以确保变量值的唯一性。这种访问方式被称为原子访问。互锁函数及其功能见如下列表:
函数参数和功能
InterlockedIncrement参数为PLONG类型。此函数使一个LONG变量增1
InterlockedDecrement参数为PLONG类型。此函数使一个LONG变量减1
InterlockedExchangeAdd参数1为PLONG类型,参数2为LONG类型。此函数将参数2赋给参数1指向的值
InterlockedExchange参数1为PLONG类型,参数2为LONG类型。此函数将参数2的值赋给参数1指向的值
InterlockedExchangePointer参数为PVOID* 类型,参数2为PVOID类型。此函数功能同上。具体参见帮助
InterlockedCompareExchange参数1为PLONG类型,参数2为LONG类型,参数3为LONG类型。此函数将参数1指向的值与参数3比较,相同则把参数2的值赋给参数1指向的值。不相同则不变
InterlockedCompareExchangePointer参数1为PVOID* 类型,参数2为PVOID类型,参数3为PVOID。此函数功能同上。具体参见帮助
2、临界区
临界区对象运行在用户模式。它能保证在临界区内所有被访问的资源不被其它线程访问,直到当前线程执行完临界区代码。除了API外,MFC也对临界区函数进行了封装。临界区相关函数:
void InitializeCriticalSection ( LPCRITICAL_SECTION );
void EnterCriticalSection ( LPCRITICAL_SECTION );
void LeaveCriticalSection ( LPCRITICAL_SECTION );
void DeleteCriticalSection ( LPCRITICAL_SECTION );
举例如下:
void CriticalSectionExample (void)
{
CRITICAL_SECTION csMyCriticalSection;
InitializeCriticalSection (&csMyCriticalSection); ///初始化临界区变量
__try
{
EnterCriticalSection (&csMyCriticalSection); ///开始保护机制
///此处编写代码
}
__finally ///异常处理,无论是否异常都执行此段代码
{
LeaveCriticalSection (&csMyCriticalSection); ///撤销保护机制
}
}
MFC类使用更简单:
CCriticalSection cs;
cs.Lock();
///编写代码
cs.Unlock();
使用临界区要注意的是避免死锁。当有两个线程,每个线程都有临界区,而且临界区保护的资源有相同的时候,这时就要在编写代码时多加考虑。
3、事件对象
事件对象运行在内核模式。与用户模式不同,内核模式下线程利用等待函数来等待所需要的事件、信号,这个等待过程由操作系统内核来完成,而线程处于睡眠状态,当接收到信号后,内核恢复线程的运行。内核模式的优点是线程在等待过程中并不浪费CPU时间,缺点是从用户模式切换到内核模式需要一定的时间,而且还要切换回来。在讲解事件对象前应该先谈谈等待函数。等待函数有四个。具体参数和功能见下表:
函数参数和功能
WaitForSingleObject参数1为HANDLE类型,参数2为DWORD类型。此函数等待参数1标识的事件,等待时间为参数2的值,单位ms。如果不超时,当事件成为有信号状态时,线程唤醒继续运行。
WaitForMultipleObjects参数1为DWORD类型,参数2为HANDLE * 类型,参数3为BOOL类型,参数4为DWORD类型。此函数等待参数2指向的数组中包含的所有事件。如果不超时,当参数3为FALSE时,只要有一个事件处于有信号状态,函数就返回这个事件的索引。参数3为TRUE时,等待所有事件都处于有信号状态时才返回。
MsgWaitForMultipleObjects参数1为DWORD类型,参数2为LPHANDLE类型,参数3为BOOL类型,参数4为DWORD类型,参数5为DWORD类型。此函数功能上同WaitForMultipleObjects函数相似,只是多了一个唤醒掩码。唤醒掩码都是和消息有关的。此函数不但能够为事件等待,还能为特定的消息等待。其实这个函数就是专为等待消息而定义的。
MsgWaitForMultipleObjectsEx参数1为DWORD类型,参数2为LPHANDLE类型,参数3为DWORD类型,参数4为DWORD类型,参数5为DWORD类型。此函数是MsgWaitForMultipleObjects函数的扩展。将原来函数的参数3除掉,添加参数5为标志。标志有两个值:0或MWMO_INPUTAVAILABLE。
如果一个线程既要执行大量任务同时又要响应用户的按键消息,这两个专用于等待消息的函数将非常有用。
和事件有关的函数有:
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPTSTR lpName);
BOOL SetEvent(HANDLE hEvent );
BOOL PulseEvent(HANDLE hEvent);
BOOL ResetEvent(HANDLE hEvent);
HANDLE OpenEvent(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName );
事件对象是最常用的内核模式同步方法。它包含一个使用计数和两个BOOL变量。其中一个BOOL变量指定这个事件对象是自动重置还是手工重置。另一个BOOL变量指定当前事件对象处于有信号状态还是无信号状态。
函数CreateEvent创建一个事件对象,参数1必须为NULL,参数2指定是否手工重新设置事件对象的状态。如果为FALSE,当等待函数接到信号并返回后此事件对象被自动置为无信号状态。这时等待此事件对象的其它线程就不会被唤醒,因为事件对象已经被置为无信号状态。如果参数2设置为TRUE,当等待函数接到信号并返回后事件对象不会被自动置于无信号状态,其它等待此事件对象的线程都能够被唤醒。用ResetEvent函数可以手工将事件对象置为无信号状态。相反SetEvent函数将事件对象置为有信号状态。PulseEvent函数将事件对象置为有信号状态,然后立即置为无信号状态,在实际开发中这个函数很少使用。OpenEvent函数打开已经创建的事件对象,一般用于不同进程内的线程同步。在调用CreateEvent创建一个事件对象时,传递一个名字给参数4,这样在其它进程中的线程就可以调用OpenEvent函数并指定事件对象的名字,来访问这个事件对象。
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- C语言多线程的详细教程资料说明 10次下载
- 关于进程与线程的解析PDF文件资料
- windows应用程序读取进程的内存工具免费下载 1次下载
- Windows CE 进程、线程和内存管理三 0次下载
- Windows CE 进程、线程和内存管理一 0次下载
- Windows CE 电源管理解析 0次下载
- 基于Windows 操作系统内核驱动的多核CPU 线程管理 0次下载
- 用多线程实现GPS接收机与PDA在Windows CE下的串口通 5次下载
- Windows CE详解 67次下载
- 基于Windows CE的GPS串行通信的实现
- 基于Windows CE的数控软件开发与实现
- 基于Windows CE嵌入式系统的智能小区广告机的设计
- Windows线程、窗口与消息内在机制研究
- Windows CE下多线程串口通信
- WINDOWS核心编程 (pdf下载)
- 线程是什么的基本单位 进程与线程的本质区别 622次阅读
- 进程和线程的概念及其区别 759次阅读
- RTOS中的线程、进程和协程详解 1561次阅读
- 关于Python多进程和多线程详解 678次阅读
- Java多线程的用法 831次阅读
- 程序中进程和线程的区别 519次阅读
- 进程(线程)精细化控制中方法的使用 474次阅读
- 什么是多线程 1097次阅读
- 为什么在JVM中线程崩溃不会导致JVM进程崩溃呢? 561次阅读
- 基于Windows NT多线程实现智能蓄电池远程监控系统的设计 1748次阅读
- 如何管理Linux 的内存分页? 3713次阅读
- 如何避免僵尸进程,多线程的实现原理 8221次阅读
- 如何选好多线程和多进程 2880次阅读
- Windows CE.NET 4.2下的串行通信技术讲解 1596次阅读
- 一文读懂线程、进程、程序之间的不同 1286次阅读
下载排行
本周
- 1TC358743XBG评估板参考手册
- 1.36 MB | 330次下载 | 免费
- 2开关电源基础知识
- 5.73 MB | 6次下载 | 免费
- 3100W短波放大电路图
- 0.05 MB | 4次下载 | 3 积分
- 4嵌入式linux-聊天程序设计
- 0.60 MB | 3次下载 | 免费
- 5基于FPGA的光纤通信系统的设计与实现
- 0.61 MB | 2次下载 | 免费
- 6基于FPGA的C8051F单片机开发板设计
- 0.70 MB | 2次下载 | 免费
- 751单片机窗帘控制器仿真程序
- 1.93 MB | 2次下载 | 免费
- 8基于51单片机的RGB调色灯程序仿真
- 0.86 MB | 2次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 2555集成电路应用800例(新编版)
- 0.00 MB | 33564次下载 | 免费
- 3接口电路图大全
- 未知 | 30323次下载 | 免费
- 4开关电源设计实例指南
- 未知 | 21548次下载 | 免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB | 15349次下载 | 免费
- 6数字电路基础pdf(下载)
- 未知 | 13750次下载 | 免费
- 7电子制作实例集锦 下载
- 未知 | 8113次下载 | 免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB | 6653次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935054次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537796次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191185次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183278次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138040次下载 | 免费
评论
查看更多