Larbin源代码分析[7]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 ;

posted on 2011-10-24 17:14  zhoulinhu  阅读(341)  评论(0编辑  收藏  举报

导航