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
//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