BOOST-OSCHINA社区的一些经典C/C++例子

1. 一个简单的mutex, condition实现, 用于在win平台下替代boost.mutex和boost.condition. 

实际中应该私有化拷贝构造函数和重截赋值操作, 以防拷贝或赋值. 

condition.h

//
// condition.h
// ~~~~~~~~~~~
//
// Copyright (c) 2011 Jack (jack.wgm@gmail.com)
//
 
#ifndef __CONDITION_H__
#define __CONDITION_H__
 
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
 
#include "mutex.h"
 
class condition
{
public:
   condition()
      : m_event(NULL)
   {
      m_event = CreateEvent(NULL, FALSE, FALSE, NULL);
   }
   virtual ~condition()
   {
      if (m_event)
         CloseHandle(m_event);
   }
 
public:
   inline void wait()
   {
      do_wait(INFINITE);
   }
 
   inline void wait(mutex::scoped_lock& lock)
   {
      if (lock.is_relocked())
         lock.unrelock();
      HANDLE semaphore = CreateSemaphore(NULL, 1, 1, NULL);
      WaitForSingleObject(semaphore, INFINITE);
      lock.attach_semaphore(semaphore);
      lock.unlock();
      do_wait(INFINITE);
      lock.lock();
   }
 
   inline bool timed_wait(DWORD millisec)
   {
      return do_wait(millisec);
   }
 
   inline void timed_wait(mutex::scoped_lock& lock, DWORD millisec = INFINITE)
   {
      if (lock.is_relocked())
         lock.unrelock();
      HANDLE semaphore = CreateSemaphore(NULL, 1, 1, NULL);
      WaitForSingleObject(semaphore, INFINITE);
      lock.attach_semaphore(semaphore);
      lock.unlock();
      do_wait(millisec);
      lock.lock();
   }
    
   inline void notify()
   {
      SetEvent(m_event);
   }
 
protected:
   inline bool do_wait(DWORD millisec)
   {
      DWORD ret = WaitForSingleObject(m_event, millisec);
      if (ret == WAIT_OBJECT_0)
         return true;
      if (ret == WAIT_TIMEOUT)
         return false;
      return false;
   }
 
protected:
   HANDLE m_event;
};
 
#endif // __CONDITION_H__

mutex.h  

//
// mutex.h
// ~~~~~~~
//
// Copyright (c) 2011 Jack (jack.wgm@gmail.com)
//
 
#ifndef __MUTEX_H__
#define __MUTEX_H__
 
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
 
class mutex
{
public:
   class scoped_lock
   {
      friend class condition;
   public:
      scoped_lock(mutex& m)
         : m_mutex(m)
         , m_is_relocked(0)
         , m_semaphore(NULL)
      {
         if (m_is_relocked && m_semaphore)
         {
            DWORD ret = WaitForSingleObject(m_semaphore, INFINITE);
            switch (ret)
            {
               case WAIT_OBJECT_0:
                  break;
               case WAIT_TIMEOUT:
                  assert(0);
                  break;
               default:
                  break;
            }
         }
         m_mutex.lock();
      }
 
      ~scoped_lock()
      {
         unrelock();
         if (m_mutex.is_locked())
            m_mutex.unlock();
      }
 
   public:
      inline void lock()
      {
         m_mutex.lock();
      }
 
      inline void unlock()
      {
         if (m_mutex.is_locked())
            m_mutex.unlock();
      }
 
   protected:
      inline bool is_relocked()
      {
         return m_is_relocked;
      }
 
      inline void unrelock()
      {
         if (m_is_relocked && m_semaphore)
         {
            m_is_relocked = 0;
            ReleaseSemaphore(m_semaphore, 1, NULL);
            CloseHandle(m_semaphore);
            m_semaphore = NULL;
         }
      }
 
      inline void attach_semaphore(const HANDLE& semaphore)
      {
         m_is_relocked = 1;
         m_semaphore = semaphore;
      }
 
   protected:
      mutex& m_mutex;
      int m_is_relocked;
      HANDLE m_semaphore;
   };
 
public:
   mutex()
   {
      SYSTEM_INFO sys;
      GetSystemInfo(&sys);
      if (sys.dwNumberOfProcessors > 1)
         InitializeCriticalSectionAndSpinCount(&m_cs, 0x80000400);
      else
         InitializeCriticalSection(&m_cs);
   }
 
   virtual ~mutex()
   {
      DeleteCriticalSection(&m_cs);
   }
 
public:
   inline void lock()
   {
      EnterCriticalSection(&m_cs);
   }
 
   inline void unlock()
   {
      LeaveCriticalSection(&m_cs);
   }
 
   inline bool is_locked()
   {
      return m_cs.LockCount != -1;
   }
 
protected:
   CRITICAL_SECTION m_cs;
};
 
#endif // __MUTEX_H__

2. c++的bind简单实现

bind.h

namespace
{
    class placeholder_ {};
    placeholder_ __1;
}
 
template <typename R, typename T, typename Arg>
class simple_bind_t
{
private:
    typedef R (T::*F)(Arg);
    F f_;
    T* t_;
    Arg& a_;
 
public:
    simple_bind_t(F f, T* t, Arg &a)
        : f_(f), t_(t), a_(a)
    {}
 
    R operator()()
    {
        return (t_->*f_)(a_);
    }
};
 
template <typename R, typename T, typename Arg>
class simple_bind_t2
{
private:
    typedef R (T::*F)(Arg);
    F f_;
    T* t_;
 
public:
    simple_bind_t2(F f, T* t)
        : f_(f), t_(t)
    {}
 
    R operator()(Arg& a)
    {
        return (t_->*f_)(a);
    }
};
 
template <typename R, typename T, typename Arg>
simple_bind_t<R, T, Arg> simple_bind(R (T::*f)(Arg), T* t, Arg& a)
{
    return simple_bind_t<R, T, Arg>(f, t, a);
}
 
template <typename R, typename T, typename Arg>
simple_bind_t2<R, T, Arg> simple_bind(R (T::*f)(Arg), T* t, placeholder_& a)
{
    return simple_bind_t2<R, T, Arg>(f, t);
}
 
class bind_test
{
public:
    void print_string(const std::string str)
    {
        printf("%s", str.c_str());
    }
};
 
void test()
{
    bind_test t;
    std::string h = "hehe\n";
    simple_bind(&bind_test::print_string, &t, h)();
    simple_bind(&bind_test::print_string, &t, __1)(h);
    boost::function<void (const std::string)> f;
    f = simple_bind(&bind_test::print_string, &t, __1);
    f(h);
}

运行结果:

test函数返回结果应该是:
hehe
hehe
hehe

3. 使用Boost库实现的线程池

//My_task_queue.h :
//*************************************************************************
//Copyright: 
//Author:     Sail
//Filename:   My_task_queue.h 
//Last Mod time: 
//*************************************************************************
//Remarks:
//任务队列用来管理一系列的任务,多个工作线程阻塞在队列的条件变量上,当有任务
//加入时,则唤醒工作线程,工作完毕后继续阻塞
//
//*************************************************************************
#ifndef MY_TASK_QUEUE
#define MY_TASK_QUEUE
 
#include <queue>
#include <boost/thread.hpp>
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
 
//定义任务
typedef boost::function<void(void)> my_task;
 
class Task_queue:boost::noncopyable
{
public:
    void push_task(const my_task & task_func)
    {
        boost::unique_lock<boost::mutex> lock(my_mutex);
        my_queue.push(task_func);
        cond.notify_one();          
    }
    my_task get_task()
    {
        boost::unique_lock<boost::mutex> lock(my_mutex);
        if(my_queue.size()==0)
        {
            cond.wait(lock);
        }
        my_task task(my_queue.front());
        my_queue.pop();
        return task;
    }
    int get_size()
    {
        return my_queue.size();
    }
private:
    std::queue<my_task> my_queue;
    boost::condition_variable_any cond;
    boost::mutex my_mutex;
};
 
#endif
//My_thread_pool.h :
//*************************************************************************
//Copyright: 
//Author:     Sail
//Filename:    
//Last Mod time: My_thread_pool
//*************************************************************************
//Remarks:
//线程池使用boost中的thread_group来管理和创建工作线程,使其阻塞在任队列中
//
//*************************************************************************
 
#ifndef MY_THREAD_POOL
#define MY_THREAD_POOL
 
#include <boost/thread.hpp>
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
 
#include "My_task_queue.h"
 
typedef boost::function<void(void)> my_task;
 
class My_thread_pool:boost::noncopyable
{
public:
    My_thread_pool(int num):thread_num(num),is_run(false){}
    ~My_thread_pool(){}
    void init()
    {
        is_run=true;
        if(thread_num<=0)
            return;
        for(int i=0;i<thread_num;++i)
        {
            my_thread_group.add_thread(new boost::thread(boost::bind(&My_thread_pool::run,this)));
        }   
    }
 
    void stop()
    {
        is_run=false;
    }
 
    void  post(const my_task & task)
    {
        my_queue.push_task(task);
    }
 
    void wait()
    {
        my_thread_group.join_all();
    }
     
private:
    Task_queue my_queue;
    boost::thread_group my_thread_group;
    int thread_num;
    volatile bool is_run;
    void run()
    {
        while(is_run)
        {
 
            my_task task=my_queue.get_task();
            task();
        }
    }
};
 
#endif
// Thread_pool.cpp : 定义控制台应用程序的入口点。
//
//Test.cpp :
//*************************************************************************
//Copyright: 
//Author:     Sail
//Filename:    
//Last Mod time: 
//*************************************************************************
//Remarks:
//测试用例
//
//*************************************************************************
#include "stdafx.h"
#include "My_task_queue.h"
#include "My_thread_pool.h"
#include <iostream>
 
typedef boost::function<void(void)> my_task;
 
void print_task(int i)
{
    printf("I'm task %d\n",i);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    My_thread_pool tp(4);
    tp.init();
     
    my_task t[4];
    for (int i= 0; i<4;++i)
    {
        t[i]=boost::bind(print_task,i+1);
        tp.post(t[i]);
    }
     
    tp.wait();
    return 0;
}

参考:

[1] https://www.oschina.net/code/snippet_54334_1856

[2] https://www.oschina.net/code/snippet_54334_10775

[3] https://www.oschina.net/code/snippet_170948_18231

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Boost库由Boost社区组织开发、维护。其目的是为C++程序员提供免费、同行审查的、可移植的程序库。Boost库可以与C++标准库完美共同工作,并且为其提供扩展功能。Boost库使用Boost License来授权使用,根据该协议,商业的非商业的使用都是允许并鼓励的。 Boost社区建立的初衷之一就是为C++的标准化工作提供可供参考的实现,Boost社区的发起人Dawes本人就是C++标准委员会的成员之一。在Boost库的开发中,Boost社区也在这个方向上取得了丰硕的成果。在送审的C++标准库TR1中,有十个Boost库成为标准库的候选方案。在更新的TR2中,有更多的Boost库被加入到其中。从某种意义上来讲,Boost库成为具有实践意义的准标准库。 可下载Boost C++ Libraries安装boost库。大部分boost库功能的使用只需包括相应头文件即可,少数(如正则表达式库,文件系统库等)需要链接库。里面有许多具有工业强度的库,如graph库。 大部分boost库功能的使用只需包括相应头文件即可,少数(如正则表达式库,文件系统库等)需要链接库。里面有许多具有工业强度的库,如graph库。 很多Boost中的库功能堪称对语言功能的扩展,其构造用尽精巧的手法,不要贸然的花费时间研读。Boost另外一面,比如Graph这样的库则是具有工业强度,结构良好,非常值得研读的精品代码,并且也可以放心的在产品代码中多多利用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值