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