复习笔记之二--用户方式线程同步
2013-12-26 09:47
246 查看
A、原子访问:互锁函数家族
执行原理:对于X86CPU,函数对总线发出一个硬件信号,防止另一个CPU(线程)访问同一地址(地址保护);对于AlphaCPU,函数执行以下操作:
1)打开CPU中的一个特殊的位标志,并注明被访问的内存地址。
2)将内存的值读入一个寄存器。
3)修改该寄存器。
4)如果CPU中的特殊位标志是关闭的,则转入第二步。否则,特殊位标志仍然是打开的,
寄存器的值重新存入内存。
函数1:
//*******************************************************************//
//输入参数:Addend长变量地址(要改变的值),Value增长的长度(可以是负数)//
//****输出参数:Addend原始值******************************//
//****函数作用:实现以原子操作同步线程,使得变量递增(递减)**********//
//*******************************************************************//
Example:
Longg_gx;
DWORDWINAPIThread()
{
InterlockedExchangeAdd(&g_gx,1);//相当于g_gx++而其他线程不可以访问g_gx
}
函数2:
//*******************************************************************//
//输入参数:Target长变量地址(被替换的值),Value要替换的值(可以是负数)//
//****输出参数:Target原始值******************************//
//****函数作用:实现以原子操作同步线程,使得Value替换目标变量**********//
//*******************************************************************//
B、临界区同步
执行原理:在任何代码执行前,临界区独占某些资源的访问权,使得其他代码无权访问。
Critical_Section声明临界区全局变量
//初始化临界区变量,并加入循环锁,
执行原理:对于X86CPU,函数对总线发出一个硬件信号,防止另一个CPU(线程)访问同一地址(地址保护);对于AlphaCPU,函数执行以下操作:
1)打开CPU中的一个特殊的位标志,并注明被访问的内存地址。
2)将内存的值读入一个寄存器。
3)修改该寄存器。
4)如果CPU中的特殊位标志是关闭的,则转入第二步。否则,特殊位标志仍然是打开的,
寄存器的值重新存入内存。
函数1:
//*******************************************************************//
//输入参数:Addend长变量地址(要改变的值),Value增长的长度(可以是负数)//
//****输出参数:Addend原始值******************************//
//****函数作用:实现以原子操作同步线程,使得变量递增(递减)**********//
//*******************************************************************//
long_InterlockedExchangeAdd(
longvolatile*Addend,
longValue
);
__int64_InterlockedExchangeAdd64(//64位
__int64volatile*Addend,
__int64Value
);
Example:
Longg_gx;
DWORDWINAPIThread()
{
InterlockedExchangeAdd(&g_gx,1);//相当于g_gx++而其他线程不可以访问g_gx
}
函数2:
//*******************************************************************//
//输入参数:Target长变量地址(被替换的值),Value要替换的值(可以是负数)//
//****输出参数:Target原始值******************************//
//****函数作用:实现以原子操作同步线程,使得Value替换目标变量**********//
//*******************************************************************//
long_InterlockedExchange(
long*Target,
longValue
);
__int64_InterlockedExchange64(//64位
__int64*Target,
__int64Value
);
void*_InterlockedExchangePointer(//64位
void*volatile*Target,
void*Value
);
Example: BOOLIsUseResource=FALSE;//判断是否资源正在使用的变量 DWORDWINAPIThread()//循环锁实现缺点:CPU不断比较,浪费资源 { while(InterlockedExchange(&IsUseResource,true)==true) { Sleep(0);//资源正在被其他线程使用,继续等待 } //开始使用资源 InterlockedExchange(&IsUseResource,false);//资源使用完毕释放权限 } 函数三: //*******************************************************************// //输入参数:Destination长变量地址(被替换的值),Exchange要替换的值(可以是负数)Comperand进行比较的对象// //****输出参数:Destination原始值******************************// //****函数作用:实现以原子操作同步线程,实现Destination指向的值和Comperand的值进行比较,若匹配,进行Exchange替换,否则不变**********// //*******************************************************************// [code]long_InterlockedCompareExchange(
longvolatile*Destination,
longExchange,
longComperand
);注意:在线程中传递变量的地址时,变量定义不需要加“volatile”限定词,因为即使修改,也是直接对内存地址进行操作。若在线程中传递变量的值时,变量的定义必须加“volatile”限定词,作用是允许除应用程序本身外的东西可以修改此值,如操作系统。
B、临界区同步
执行原理:在任何代码执行前,临界区独占某些资源的访问权,使得其他代码无权访问。
Critical_Section声明临界区全局变量
//初始化临界区变量,并加入循环锁,
dwSpinCount
:循环次数。应用多处理器
BOOLWINAPIInitializeCriticalSectionAndSpinCount(
__outLPCRITICAL_SECTIONlpCriticalSection,
__inDWORDdwSpinCount
);
//初始化临界区变量,不加入循环锁,应用于单处理器。
voidWINAPIInitializeCriticalSection(
__outLPCRITICAL_SECTIONlpCriticalSection
);
//释放临界区变量(对应初始化临界区变量函数使用,成对出现)
voidWINAPIDeleteCriticalSection(
__inoutLPCRITICAL_SECTIONlpCriticalSection
);//使用临界区保护资源,若资源正在使用,请求的线程进入等待状态。(进入内核方式)
[code]voidWINAPIEnterCriticalSection(
__inoutLPCRITICAL_SECTIONlpCriticalSection
);//使用临界区保护资源,若资源正在使用,请求的线程不进入等待状态,返回true时,获得访问权。(一直在用户方式)
BOOLWINAPITryEnterCriticalSection(
__inoutLPCRITICAL_SECTIONlpCriticalSection
);
//释放资源,更新资源状态(与保护资源成对出现)
voidWINAPILeaveCriticalSection(
__inoutLPCRITICAL_SECTIONlpCriticalSection
);举例说明:
CRITICAL_SECTIONCriticalSection;
voidmain()
{
//Initializethecriticalsectiononetimeonly.
if(!InitializeCriticalSectionAndSpinCount(&CriticalSection,
0x80000400))
return;
...
//Releaseresourcesusedbythecriticalsectionobject.
DeleteCriticalSection(&CriticalSection)
}
DWORDWINAPIThreadProc(LPVOIDlpParameter)
{
...
//Requestownershipofthecriticalsection.
EnterCriticalSection(&CriticalSection);
//
也可以是if(TryEnterCriticalSection(&g_s))
//Accessthesharedresource.
//Releaseownershipofthecriticalsection.
LeaveCriticalSection(&CriticalSection);
...
}[/code]
相关文章推荐
- windows笔记-【用户方式线程同步】互锁的函数家族
- windows笔记-【用户方式线程同步】关键代码段
- -【用户方式线程同步】互锁的函数家族
- 复习笔记10 switch 编译器优化的两种方式 和if的效率对比
- java笔记--关于线程同步(7种同步方式)
- java笔记--关于线程同步(5种同步方式)
- 用户方式中线程同步
- java笔记--关于线程同步(7种同步方式)
- 学习笔记18 复习asp.net页面传参数的几种方式
- java笔记--关于线程同步(5种同步方式)【转】
- java笔记--关于线程同步(5种同步方式)
- java笔记--关于线程同步(7种同步方式)
- java笔记--关于线程同步(7种同步方式)
- java笔记--关于线程同步(5种同步方式)
- java笔记--关于线程同步(5种同步方式)
- Windows核心编程笔记 用户模式下的线程同步
- java笔记--关于线程同步(5种同步方式)
- android菜鸟学习笔记29----Android应用向用户发送提示信息的方式总结
- ajax 学习笔记之二 POST GET方式提交数据
- C8、 用户方式的线程同步