自己动手写线程池之锁的优化
来源:互联网 发布:收集用户行为数据 编辑:程序博客网 时间:2024/05/01 09:37
问题描述
线程池将任务Task
添加到工作队列中,该队列使用STL List
实现。每次添加任务的时候,都需要获取线程锁,然后操作队列。
template <typename Item>
void ThreadQueue<Item>::Push(const Item &item)
{
{
ThreadLocker::Locker lock(&_locker);
_queue.push_back(item);
}
_locker.Signal();
}
问题来了,如何实现一个批量插入接口?
template <typename Item, typename Type>
void ThreadQueue<Item, Type>::Push(const QueueType &queue)
{
int notify_cnt = 0;
{
ThreadLocker::Locker lock(&_locker);
typename QueueType::const_iterator iter = queue.begin();
for ( ; iter != queue.end(); iter++)
{
_queue.push_back(*iter);
notify_cnt += 1;
}
}
for (int i = 0; i < notify_cnt; i++)
{
_locker.Signal();
}
}
批量操作,需要记录添加item的数量,在添加完成之后,进行Signal,通知工作线程,有新的任务到来。但这非常不方便,在任务需要批量操作的时候,都需要计数器。换个思路,能不能将计数器搬到锁管理类内,在解锁的时候,自动进行通知呢?
/* 理想代码 */
template <typename Item, typename Type>
void ThreadQueue<Item, Type>::Push(const QueueType &queue)
{
ThreadLocker::Locker lock(&_locker);
typename QueueType::const_iterator iter = queue.begin();
for ( ; iter != queue.end(); iter++)
{
_queue.push_back(*iter);
_locker.Notify();
}
}
解决方法
在锁管理类ThreadLocker
中,引入计数器_notify_num
。Notify
的时候,进行Signal操作,而仅仅是将计数器自增,在解锁的时候,进行实际操作。
/* 计数器自增 */
void ThreadLocker::Notify()
{
if (_notify_num != -1)
{
_notify_num += 1;
}
}
/* 解锁操作 */
void ThreadLocker::UnLock()
{
_thread_mutex.UnLock();
NotifyImpl();
}
/* 实际通知 */
void ThreadLocker::NotifyImpl()
{
if (_notify_num != 0)
{
if (_notify_num == -1)
{
BroadCast();
}
else
{
for (int i = 0; i < _notify_num; i++)
{
Signal();
}
}
_notify_num = 0;
}
}
NOTE: 在获取锁的时候,notify_num必须清0,这样,在notify的时候,自增才有效。获取锁的时机不仅在Lock函数,还在Wait、TimeWait返回之后。
代码
https://github.com/spch2008/threadpool/blob/master/src/thread_locker.cpp
0 0
- 自己动手写线程池之锁的优化
- 自己动手写线程池之锁的管理
- 自己动手写线程池之线程
- 自己动手写线程池之异常
- 自己动手写线程池之线程池实现
- 自己动手,写一个简单的线程池(1)
- 自己动手,写一个简单的线程池(2)
- 自己动手,写一个简单的线程池(3)
- 自己动手,写自己的lazyload,让插件凉快去——网站优化之图片延时加载
- 自己动手实现简单的线程池
- 自己动手写数据库连接池
- 自己动手写数据库连接池
- 自己动手写对象池
- 《自己动手写操作系统》之ReadSector
- 自己动手写操作系统 之 连接器
- 自己动手写编译器之序
- 自己动手写操作系统之参考资料
- 自己动手写一个简单的Shell之二:运行程序
- 九度OJ-1166
- 女人眼中男人最性感4部位
- 字典里有个数组,数组里面存放着几个不相同的字典模型怎么用MJExtension解析,
- Android基础-3
- 流媒体文件应用常见问题解答
- 自己动手写线程池之锁的优化
- Android基础-4
- 定价类型
- 【JZOJ 4598】 准备食物
- 用JS获取地址栏参数的方法
- Android基础-5
- 8string Math date history计时器对象
- 流媒体完全手册
- Android基础-6