ACE中线程的实现原理

摘自:http://www.acejoy.com/bbs/dispbbs.asp?boardID=23&ID=840&page=4

向ACE的高手们学习致敬!

=========================================================================

ACE中线程的实现原理
1.ACE中对线程的封装
1.1ACE_Thread实现原理
ACE_Thread 提供了对OS 的线程调用的简单包装,这些调用处理线程创建、挂起、取消和删除等问题。它提供给应用程序员一个简单易用的接口,可以在不同的线程API 间移植。ACE_Thread 是非常“瘦”的包装,有着很少的开销。其大多数方法都是内联的,因而等价于对底层OS 专有线程接口的直接调用。ACE_Thread 中的所有方法都是静态的,而且该类一般不进行实例化。
ACE_Thread类中的几个重要的静态函数:
1)建立线程:
size_t spawn_n (size_t n,
                         ACE_THR_FUNC func,
                         void *arg = 0,
                         long flags = THR_NEW_LWP | THR_JOINABLE,
                         long priority = ACE_DEFAULT_THREAD_PRIORITY,
                         void *stack[] = 0,
                         size_t stack_size[] = 0,
                         ACE_Thread_Adapter *thread_adapter = 0)
     {
         …
         for (i = 0; i < n; i++)
         // Bail out if error occurs.
              if (ACE_OS::thr_create (func,
                            arg,
                            flags,
                            &t_id,
                            0,
                            priority,
                            stack == 0 ? 0 : stack[i],
                            stack_size == 0 ? 0 : stack_size[i],
                            thread_adapter) != 0)
                   break;
         return i;
}
该函数可以同时创建n个线程。该函数在中途遇到创建线程失败的情况出现时会自动跳出,而不继续创建。
size_t ACE_Thread::spawn_n (ACE_thread_t thread_ids[],
                     size_t n,
                     ACE_THR_FUNC func,
                     void *arg,
                     long flags,
                     long priority,
                     void *stack[],
                     size_t stack_size[],
                     ACE_hthread_t thread_handles[],
                     ACE_Thread_Adapter *thread_adapter)
该函数可以使用thread_ids[]记录所有创建成功的线程的id号。
而对于spawn函数则只能够创建单个线程。
1.2ACE_Task_Base实现原理
ACE_Task_Base 是ACE 中的任务或主动对象“处理结构”的基类。在ACE 中使用了此类来实现主动对象模式。所有希望成为“主动对象”的对象都必须从此类派生。你也可以把ACE_TASK 看作是更高级的、更为面向对象的线程类。
ACE_Task_Base调用时必须重写svc方法,并且在使用时保证调用了activate方法。
最常见的使用流程如下例:
class TaskOne: public ACE_Task_Base
{
public:
//Implement the Service Initialization and Termination methods
int open(void*)
{
activate();
return 0;
}
int close(u_long)
{
return 0;
}
int svc(void)
{
// do thread specific work here
//.......
//.......
return 0;
}
};
int main(int argc, char *argv[])
{
//Create the task
TaskOne *one=new TaskOne;
//Start up the task
one->open(0);
//wait for all the tasks to exit
ACE_Thread_Manager::instance()->wait();
ACE_DEBUG((LM_DEBUG,"(%t) Main Task ends /n"));
}
ACE_Task_Base中的关键方法:
①open 
用户改写该函数,在其中调用ACE_Tase_Base::activate()方法。
②svc  
    用户必须重新实现该方法,用于供线程调用。
③close
    用户可以修改该函数用于完成在线程结束前的清理工作。
④svc_run
    该方法为静态函数,作为线程的回调函数。该函数中调用了svc方法。这里有一个技巧ACE_Task_Base在实现svc_run函数时将ACE_Task_Base类的对象以参数形式传进了svc_run方法中:
ACE_Task_Base::activate(…)
{
    …
        //第三个参数为传入回调函数的参数指针。
          this->thr_mgr_->spawn_n (n_threads,
                               &ACE_Task_Base::svc_run,
                               (void *) this,
                               flags,
                               priority,
                               grp_id,
                               task,
                               thread_handles,
                               stack,
                          stack_size);

}
ACE_Task_Base::svc_run (void *args)
{

     ACE_Task_Base *t = (ACE_Task_Base *) args;
     …
     // Call the Task's svc() hook method.
     int svc_status = t->svc ();
     …
}
1.3ACE_Thread_Adapter实现原理
     在说明ACE_Thread_Adapter类的实现原理之前我们首先要明白该类有什么用,被用在哪里。从后缀的Adapter可以猜测该类属于适配器类,而在设计模式中适配器设计模式往往是用来转换接口而用。
1.4 ACE_Thread_Manager实现原理
ACE_Thread_Descriptor类的对象存放程序的描述信息。
ACE_Thread_Manager的实现原理简单概括起来就是:将需要管理的线程的线程信息保存在特定的双向链表中,以供需要操作线程时使用。
将线程加入管理类的方法有两种:
1)使用ACE_Thread_Manager的spawn系列方法启动线程后会自动加入到ACE_Thread_Manager管理的线程双向链表中。
2)直接使用ACE_Thread_Manager的insert_thr方法直接将已启动的线程加入到ACE_Thread_Manager管理的线程双向链表中。
※注释:
不管使用上面那种方法,最终都需要调用append_thr方法将线程信息类ACE_Thread_Descriptor的对象插入到ACE_Double_Linked_List<ACE_Thread_Descriptor> thr_list_信息双向链表中。
使用ACE_Thread_Manager的spawn系列方法最终都会调用spawn_i方法来启动线程,spawn_i方法实现过程中发生了几个关键的调用:
  ACE_Thread::spawn (…)    启动线程
  append_thr(…)       将线程信息插入到双向链表thr_list的尾端。
ACE_Thread_Manager类中对于所管理的线程对象的查找以及操作等都是同过ACE_Thread_Descriptor对象作为参数进行操作的。
    
这里只是简单研究了一下,应该足够用了。可能其中也有些错误之处,请大家指正。
 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言实现积分图实现ACE算法的代码: ```c #include <stdio.h> #include <stdlib.h> #include <opencv2/opencv.hpp> using namespace cv; void integral_image(Mat &img, Mat &integral) { int h = img.rows; int w = img.cols; integral.create(h+1, w+1, CV_32S); integral.setTo(0); for(int i=1; i<=h; i++) { for(int j=1; j<=w; j++) { integral.at<int>(i, j) = img.at<uchar>(i-1, j-1) + integral.at<int>(i-1, j) + integral.at<int>(i, j-1) - integral.at<int>(i-1, j-1); } } } void local_mean_and_variance(Mat &integral, int w_size, Mat &local_mean, Mat &local_variance) { int h = integral.rows - 1; int w = integral.cols - 1; int half_w_size = w_size / 2; local_mean.create(h, w, CV_32F); local_variance.create(h, w, CV_32F); for(int i=0; i<h; i++) { for(int j=0; j<w; j++) { int top = i - half_w_size; int left = j - half_w_size; int bottom = i + half_w_size; int right = j + half_w_size; top = top < 0 ? 0 : top; left = left < 0 ? 0 : left; bottom = bottom >= h ? h-1 : bottom; right = right >= w ? w-1 : right; int area = (bottom - top + 1) * (right - left + 1); int sum = integral.at<int>(bottom+1, right+1) + integral.at<int>(top, left) - integral.at<int>(bottom+1, left) - integral.at<int>(top, right+1); float mean = (float)sum / area; local_mean.at<float>(i, j) = mean; int sum2 = integral.at<int>(bottom+1, right+1) + integral.at<int>(top, left) - integral.at<int>(bottom+1, left) - integral.at<int>(top, right+1); float variance = (float)sum2 / area - mean * mean; local_variance.at<float>(i, j) = variance; } } } void contrast_score(Mat &local_mean, Mat &local_variance, float k, float alpha, Mat &contrast) { contrast.create(local_mean.rows, local_mean.cols, CV_32F); for(int i=0; i<local_mean.rows; i++) { for(int j=0; j<local_mean.cols; j++) { float mean = local_mean.at<float>(i, j); float variance = local_variance.at<float>(i, j); float score = k * fabs(mean) / sqrt(variance + alpha * alpha); contrast.at<float>(i, j) = score; } } } void contrast_enhancement(Mat &img, Mat &contrast, Mat &img_enhanced) { img.convertTo(img_enhanced, CV_32F); float *pImg = img_enhanced.ptr<float>(0); float *pContrast = contrast.ptr<float>(0); int size = img_enhanced.rows * img_enhanced.cols; for(int i=0; i<size; i++) { pImg[i] = pImg[i] + pContrast[i] * (pImg[i] - mean(pImg, size)); pImg[i] = pImg[i] < 0 ? 0 : pImg[i]; pImg[i] = pImg[i] > 255 ? 255 : pImg[i]; } img_enhanced.convertTo(img_enhanced, CV_8U); } int main(int argc, char **argv) { if(argc < 2) { printf("Usage: %s image_path\n", argv[0]); return -1; } Mat img = imread(argv[1], IMREAD_GRAYSCALE); if(img.empty()) { printf("Failed to load image: %s\n", argv[1]); return -1; } Mat integral, local_mean, local_variance, contrast, img_enhanced; integral_image(img, integral); local_mean_and_variance(integral, 21, local_mean, local_variance); contrast_score(local_mean, local_variance, 0.4, 1.0, contrast); contrast_enhancement(img, contrast, img_enhanced); imshow("original", img); imshow("enhanced", img_enhanced); waitKey(0); destroyAllWindows(); return 0; } ``` 其,img_path 是待处理的图像路径,w_size 是局部均值和局部方差计算时的窗口大小,k 和 alpha 是对比度得分计算时的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值