larbin源码分析(七) larbin中的2种容器4个url队列
一 larbin中的2中类型的队列
static SyncFifo<url> *URLsPriority; //最高优先级
static SyncFifo<url> *URLsPriorityWait; //次高优先级
static PersistentFifo *URLsDisk; //低优先级
static PersistentFifo *URLsDiskWait; //最低优先级
上述4个URL队列的优先级,由上到下依次递减。
四种url队列的具体使用,留待以后分析。
二 下面主要分析 SyncFifo
该类实际上为一个同步处理的先进先出的队列。
1 类的主要成员变量
uint in, out; //in表示入队指针,out表示出队指针
uint size; //表示队列的大小
T **tab; //指针的指针,T表示类模板
pthread_mutex_t lock; //互斥变量
pthread_cond_t nonEmpty; //互斥条件变量
2 一般同样的队列同步框架
(1) 放入队列中的处理
pthread_mutex_lock(&lock)
//放入队列操作
put() //入队操作
pthrad_cond_signal(&lock) //向取队列线程发送信号
pthread_mutex_unlock(&lock)
(2)从队列中取出
pthread_mutex_lock(&lock)
while(empty)
pthread_cond_wait(&nonEmpty) //执行该句的时候,会释放该Mutex锁 lock
//取队列处理
pthread_mutex_unlock(&lock)
3 成员函数
(1)构造函数
template <class T>
SyncFifo<T>::SyncFifo (uint size) { //执行的操作:构建队列缓冲区
tab = new T*[size]; //初始化头尾指针,初始化互斥变量
this->size = size;
in = 0;
out = 0;
mypthread_mutex_init (&lock, NULL);
mypthread_cond_init (&nonEmpty, NULL);
}
(2)~SyncFifo()
析构函数执行tab缓冲区的释放,以及互斥变量 ,互斥条件变量的销毁。
(3)get函数 ,取队头操作。 套用了基本框架
template <class T>
T *SyncFifo<T>::get () { //
T *tmp;
mypthread_mutex_lock(&lock);
mypthread_cond_wait(in == out, &nonEmpty, &lock); //
tmp = tab[out];
out = (out + 1) % size; //循环队列
mypthread_mutex_unlock(&lock);
return tmp;
}
(4)tryGet () 函数
该函数不使用互斥变量,直接使用互斥量,取队头操作。
若队为空,则返回NULL。
(5) put函数
该函数首先将要插入的元素插入,然后通知阻塞在该信号变量的线程,使其恢复。
插入之后,若是in==out,则表示存储空间已满,则需要重新申请一个新的空间tmp(空间为原来的2倍),
并将原来tab中的数据复制到tmp中。
具体实现 代码如下:
mypthread_mutex_lock(&lock);
tab[in] = obj;
if (in == out) { //若之前队列为空,则需要调用signal函数
mypthread_cond_broadcast(&nonEmpty);
}
in = (in + 1) % size ;
if(in == out) //处理in == out的情况,即队列已满的情况
{
T * tmp = new T *[2 * size] ; //成倍地扩展缓冲区域
for(int i = out ; i < size ; i++) //将tab中的数据 copy到tmp中
tmp[i] = tab[i] ;
for(int i = 0 ; i < out ; i++)
tmp[i+size] = tab[i] ;
int = out + size ;
size *= 2 ;
delete [] tab;
tab = tmp
}
(6)length 函数
首先需要利用互斥信号量进行互斥操作,然后由于是循环队列,所以需要使用
len = (in - out + size) % size ;