转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581771.html

ACE Lock类属

锁类属包含的类包装简单的锁定机制,比如互斥体、信号量、读/写互斥体和令牌等。这里我就以互斥体为例简单的介绍一下其使用方法,对其它的锁类进行一些简单的说明。

1.互斥体的使用。

互斥体用于保护共享的易变代码,也就是全局或静态数据。这样的数据必须通过互斥体进行保护,以防止它们在多个线程同时访问时损坏。

在ACE中可以通过ACE_Thread_Mutex实现线程的访问互斥,下面的例子演示ACE_Thread_Mutex类的使用。

#include "ace/Thread.h" 
#include "ace/Synch.h"

#include <iostream>
using namespace std;

ACE_Thread_Mutex mutex;

void* Thread1(void *arg) 
{
    mutex.acquire();
    ACE_OS::sleep(3);
    cout<<endl<<"hello thread1"<<endl;
    mutex.release();

return NULL; 
}

void* Thread2(void *arg) 
{
    mutex.acquire();
    cout<<endl<<"hello thread2"<<endl;
    mutex.release();

return NULL; 
}

int main(int argc, char *argv[]) 

    ACE_Thread::spawn((ACE_THR_FUNC)Thread1);
    
    //Thread2 比Thread1晚创建1秒钟,故后尝试获取互斥体
    ACE_OS::sleep(1);
    ACE_Thread::spawn((ACE_THR_FUNC)Thread2);
    
    while(true)
        ACE_OS::sleep(10);

return 0; 
}

ACE_Thread_Mutex主要有两个方法:

  1. acquire():用来获取互斥体,如果无法获取,将阻塞至获取到为止。
  2. release():用来释放互斥体,从而使自己或者其它线程能够获取互斥体。

当线程要访问共享资源时,首先调用acquire()方法获取互斥体,从而获取对改互斥体所保护的共享资源的唯一访问权限,访问结束时调用释放互斥体,使得其它线程能获取共享资源的访问权限。

在此例中,本来Thread2的打印消息在Thread1之前,但由于Thread1先获得互斥体,故Thread2只有待Thread1结束后才能进入临界区。读者朋友们可以通过将ACE_Thread_Mutex替换为ACE_NULL_Mutex看一下不加锁的执行结果。

2.ACE Lock类属简介。

ACE Lock类属列表如下:

名字

描述

ACE_Mutex

封装互斥机制(根据平台,可以是mutex_t、pthread_mutex_t等等)的包装类,用于提供简单而有效的机制来使对共享资源的访问序列化。它与二元信号量(binary semaphore)的功能相类似。可被用于线程和进程间的互斥。

ACE_Thread_Mutex

可用于替换ACE_Mutex,专用于线程同步。

ACE_Process_Mutex

可用于替换ACE_Mutex,专用于进程同步。

ACE_NULL_Mutex

提供了ACE_Mutex接口的"无为"(do-nothing)实现,可在不需要同步时用作替换。

ACE_RW_Mutex

封装读者/作者锁的包装类。它们是分别为读和写进行获取的锁,在没有作者在写的时候,多个读者可以同时进行读取。

ACE_RW_Thread_Mutex

可用于替换ACE_RW_Mutex,专用于线程同步。

ACE_RW_Process_Mutex

可用于替换ACE_RW_Mutex,专用于进程同步。

ACE_Semaphore

这些类实现计数信号量,在有固定数量的线程可以同时访问一个资源时很有用。在OS不提供这种同步机制的情况下,可通过互斥体来进行模拟。

ACE_Thread_Semaphore

应被用于替换ACE_Semaphore,专用于线程同步。

ACE_Process_Semaphore

应被用于替换ACE_Semaphore,专用于进程同步。

ACE_Token

提供"递归互斥体"(recursive mutex),也就是,当前持有某令牌的线程可以多次重新获取它,而不会阻塞。而且,当令牌被释放时,它确保下一个正阻塞并等待此令牌的线程就是下一个被放行的线程。

ACE_Null_Token

令牌接口的"无为"(do-nothing)实现,在你知道不会出现多个线程时使用。

ACE_Lock

定义锁定接口的接口类。一个纯虚类,如果使用的话,必须承受虚函数调用开销。

ACE_Lock_Adapter

基于模板的适配器,允许将前面提到的任意一种锁定机制适配到ACE_Lock接口。

可以简单的分为以下几类:

  1. 互斥锁
    互斥锁(通常称为"互斥体"或"二元信号量")用于保护多线程控制并发访问的共享资源的完整性。互斥体通过定义临界区来序列化多线程控制的执行,在临界区中每一时刻只有一个线程在执行它的代码。互斥体简单而高效(时间和空间)。
    ACE线程库提供了Mutex式的类(是一组互斥体对象,拥有类似的接口),他是一种简单而高效的类型是"非递归"互斥体。非递归互斥体不允许当前拥有互斥体的线程在释放它之前重新获取它。否则,将会立即发生死锁。递归互斥体在ACE Recursive_Thread_Mutex类中可移植地实现。
  2. 读者/作者锁
    读者/作者锁与互斥体相类似。例如,获取读者/作者锁的线程也必须释放它。多个线程可同时获取一个读者/作者锁用于读,但只有一个线程可以获取该锁用于写。当互斥体保护的资源用于读远比用于写要频繁时,读者/作者互斥体有助于改善并发的执行。
    ACE线程库提供了一个叫作RW_Mutex的类,在C++封装类中可移植地实现了读者/作者锁的语义。读者/作者锁将优先选择权给作者。因而,如果有多个读者和一个作者在锁上等待,作者将会首先获取它。

计数信号量
在概念上,计数信号量是可以原子地增减的整数。如果线程试图减少一个值为零的信号量的值,它就会阻塞,直到另一个线程增加该信号量的值。
计数信号量用于追踪共享程序状态的变化。它们记录某种特定事件的发生。因为信号量维护状态,它们允许线程根据该状态来作决定,即使事件是发生在过去。
信号量比互斥体效率要低,但是,它们要更为通用,因为它们无需被最初获取它们的同一线程获取和释放。这使得它们能够用于异步的执行上下文中(比如信号处理器)。ACE线程库提供一个叫作Semaphore的类来可移植地在C++包装类中实现信号量语义。

ACE线程管理机制-并发控制(1)的更多相关文章

  1. ACE线程管理机制-并发控制(3)

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581854.html ACE Condition类属 ACE Condition类属(条 ...

  2. ACE线程管理机制-并发控制(4)

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581857.html ACE Synchronization类 这一类并发控制对象一般也 ...

  3. ACE线程管理机制-并发控制(2)

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581793.html ACE Guard类属 与C一级的互斥体API相比较,Mutex包 ...

  4. ACE线程管理机制-并发控制

    ACE有若干可用于并发控制的类.这些类可划分为以下范畴: ACE Lock类属 ACE Guard类属 ACE Condition类属 ACE Synchronization类 由于篇幅较长,我分别写 ...

  5. ACE线程管理机制-面向对象的线程类ACE_Task

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/05/583231.html 我们在前一章中使用ACE_Thread包装时,你一定已经注意到了一 ...

  6. ACE线程管理机制-线程的创建与管理

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581369.html 有过在不同的操作系统下用c++进行过多线程编程的朋友对那些线程处理 ...

  7. [转载]Linux 线程实现机制分析

    本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...

  8. Linux 线程实现机制分析 Linux 线程模型的比较:LinuxThreads 和 NPTL

    Linux 线程实现机制分析 Linux 线程实现机制分析  Linux 线程模型的比较:LinuxThreads 和 NPTL http://www.ibm.com/developerworks/c ...

  9. Linux 线程实现机制分析--转

    http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 一.基础知识:线程和进程 按照教科书上的定义,进程是资源管理的最小单位,线程是程 ...

随机推荐

  1. yarn logs -applicationId命令java版本简单实现

    import java.io.DataInputStream; import java.io.EOFException; import java.io.FileNotFoundException; i ...

  2. ThinkPHP - 3 - IDE选择以及Eclipse PDT打开ThinkPHP项目

    ThinkPHP框架已部署到SAE(新浪云),且代码已获取到本地.眼前面临的问题就是,对ThinkPHP项目选择哪种开发工具(IDE)? 经过简单的查找比较,以及电脑里已装有Eclipse的因素,遂决 ...

  3. Html5 input placeholder 属性字体颜色修改。

    这篇文章主要介绍了有关HTML5 input placeholder 颜色修改方面的知识,需要的朋友可以参考下     Chrome支持input=[type=text]占位文本属性,但下列CSS样式 ...

  4. Python—文件

    def fileCopy(src, dst, srcEncoding, dstEncoding): with open(src, 'r', encoding=srcEncoding) as srcfp ...

  5. PhotoShop基础工具 -- 移动工具

    还是学点美工的东西吧, 业余爱好   比学编程还难 PS版本 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左侧的是工具栏, 每选中一个工具, 在菜单 ...

  6. android 出现Make sure the Cursor is initialized correctly before accessing data from it

    Make sure the Cursor is initialized correctly before accessing data from it 详细错误是:java.lang.IllegalS ...

  7. 3ds Max学习日记(四)

      下午去实验室见了师姐,人还挺好,给我安排了任务,和3ds max没有半毛钱关系. 附上今日的劳动成果:   板子(牌匾)   简约吊灯(看上去比较单调)   高脚杯(喝酒用的)   沙发(沙发) ...

  8. c++ int 负数 补码 隐式类型转换

    unsigned y = ; ; cout << x + y << endl; 对于上述的结果为 这里面有一个负数的补码问题和不同类型之间的隐式类型转换问题 首先负数的表示方法 ...

  9. dwarf是如何处理栈帧的?

    dwarf是如何处理栈帧的? DW_AT_frame_base 表明函数栈帧的起始点 95 < 1><0x000000ca>    DW_TAG_subprogram 96   ...

  10. touchSwipe 上下左右滑动,二指缩放 效果不好。

    $(function(){ var _showImgW; var _showImgH; var _showImgMT; var _showImgML; $("#imgDiv").s ...