larbin源碼分析(七) larbin中的2種容器4個(gè)url隊(duì)列
一 larbin中的2中類型的隊(duì)列
static SyncFifo<url> *URLsPriority; //最高優(yōu)先級(jí)
static SyncFifo<url> *URLsPriorityWait; //次高優(yōu)先級(jí)
static PersistentFifo *URLsDisk; //低優(yōu)先級(jí)
static PersistentFifo *URLsDiskWait; //最低優(yōu)先級(jí)
上述4個(gè)URL隊(duì)列的優(yōu)先級(jí),由上到下依次遞減。
四種url隊(duì)列的具體使用,留待以后分析。
二 下面主要分析 SyncFifo
該類實(shí)際上為一個(gè)同步處理的先進(jìn)先出的隊(duì)列。
1 類的主要成員變量
uint in, out; //in表示入隊(duì)指針,out表示出隊(duì)指針
uint size; //表示隊(duì)列的大小
T **tab; //指針的指針,T表示類模板
pthread_mutex_t lock; //互斥變量
pthread_cond_t nonEmpty; //互斥條件變量
2 一般同樣的隊(duì)列同步框架
(1) 放入隊(duì)列中的處理
pthread_mutex_lock(&lock)
//放入隊(duì)列操作
put() //入隊(duì)操作
pthrad_cond_signal(&lock) //向取隊(duì)列線程發(fā)送信號(hào)
pthread_mutex_unlock(&lock)
(2)從隊(duì)列中取出
pthread_mutex_lock(&lock)
while(empty)
pthread_cond_wait(&nonEmpty) //執(zhí)行該句的時(shí)候,會(huì)釋放該Mutex鎖 lock
//取隊(duì)列處理
pthread_mutex_unlock(&lock)
3 成員函數(shù)
(1)構(gòu)造函數(shù)
template <class T>
SyncFifo<T>::SyncFifo (uint size) { //執(zhí)行的操作:構(gòu)建隊(duì)列緩沖區(qū)
tab = new T*[size]; //初始化頭尾指針,初始化互斥變量
this->size = size;
in = 0;
out = 0;
mypthread_mutex_init (&lock, NULL);
mypthread_cond_init (&nonEmpty, NULL);
}
(2)~SyncFifo()
析構(gòu)函數(shù)執(zhí)行tab緩沖區(qū)的釋放,以及互斥變量 ,互斥條件變量的銷毀。
(3)get函數(shù) ,取隊(duì)頭操作。 套用了基本框架
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; //循環(huán)隊(duì)列
mypthread_mutex_unlock(&lock);
return tmp;
}
(4)tryGet () 函數(shù)
該函數(shù)不使用互斥變量,直接使用互斥量,取隊(duì)頭操作。
若隊(duì)為空,則返回NULL。
(5) put函數(shù)
該函數(shù)首先將要插入的元素插入,然后通知阻塞在該信號(hào)變量的線程,使其恢復(fù)。
插入之后,若是in==out,則表示存儲(chǔ)空間已滿,則需要重新申請一個(gè)新的空間tmp(空間為原來的2倍),
并將原來tab中的數(shù)據(jù)復(fù)制到tmp中。
具體實(shí)現(xiàn) 代碼如下:
mypthread_mutex_lock(&lock);
tab[in] = obj;
if (in == out) { //若之前隊(duì)列為空,則需要調(diào)用signal函數(shù)
mypthread_cond_broadcast(&nonEmpty);
}
in = (in + 1) % size ;
if(in == out) //處理in == out的情況,即隊(duì)列已滿的情況
{
T * tmp = new T *[2 * size] ; //成倍地?cái)U(kuò)展緩沖區(qū)域
for(int i = out ; i < size ; i++) //將tab中的數(shù)據(jù) 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 函數(shù)
首先需要利用互斥信號(hào)量進(jìn)行互斥操作,然后由于是循環(huán)隊(duì)列,所以需要使用
len = (in - out + size) % size ;