队列是我们平时开发或者学习中经常会用到的一种数据结构。今天我们来看一下3中队列的不同代码。
简单队列:
在大学的学习中,我们都应该写过队列的代码,这种代码是最基本的代码:
/* standard fifo in RAM WITHOUT synchronisation */
#ifndef FIFO_H
#define FIFO_H
#define maxUrlsBySite 40
template <class T>
class Fifo {
public:
uint in, out;
uint size;
T **tab;
/* Specific constructor */
Fifo (uint size=maxUrlsBySite);
/* Destructor */
~Fifo ();
/* give the first object and let it in */
inline T* read () { return tab[out]; }
/* read the first obj if exist */
T *tryRead ();
/* get the first object */
T *get ();
/* get the first object (non totally blocking)
* return NULL if there is none
*/
T *tryGet ();
/* add an object in the Fifo */
void put (T *obj);
/* put an obj that has just been get
* this function must be called only to put back an obj
* that has just been tken with get */
void rePut (T *obj);
/* how many items are there inside ? */
int getLength ();
/* is this fifo empty ? */
inline bool isEmpty () { return in == out; }
};
template <class T>
Fifo<T>::Fifo (uint size) {
tab = new T*[size];
this->size = size;
in = 0;
out = 0;
}
template <class T>
Fifo<T>::~Fifo () {
delete [] tab;
}
template <class T>
T *Fifo<T>::tryRead () {
if (in == out) {
return NULL;
} else {
return tab[out];
}
}
template <class T>
T *Fifo<T>::get () {
T *tmp;
assert (in != out);
tmp = tab[out];
out = (out + 1) % size;
return tmp;
}
template <class T>
T *Fifo<T>::tryGet () {
T *tmp = NULL;
if (in != out) {
// The stack is not empty
tmp = tab[out];
out = (out + 1) % size;
}
return tmp;
}
template <class T>
void Fifo<T>::put (T *obj) {
tab[in] = obj;
in = (in + 1) % size;
if (in == out) {
T **tmp;
tmp = new T*[2*size];
for (uint i=out; i<size; i++) {
tmp[i] = tab[i];
}
for (uint i=0; i<in; i++) {
tmp[i+size] = tab[i];
}
in += size;
size *= 2;
delete [] tab;
tab = tmp;
}
}
template <class T>
void Fifo<T>::rePut (T *obj) {
out = (out + size - 1) % size;
tab[out] = obj;
}
template <class T>
int Fifo<T>::getLength () {
return (in + size - out) % size;
}
#endif // FIFO_H
具有同步结构的队列:
/* this fifo will not grow
* it is synchronized
*/
#ifndef CONSTANTFIFO_H
#define CONSTANTFIFO_H
#include <assert.h>
#define mypthread_cond_wait(c,x,y) while(c) {pthread_cond_wait(x,y);}
#define mypthread_cond_broadcast(x) pthread_cond_broadcast(x)
template <class T>
class ConstantSizedFifo {
protected:
uint in, out;
uint size;
T **tab;
#ifdef THREAD_OUTPUT
pthread_mutex_t lock;
pthread_cond_t nonEmpty;
#endif
public:
/* Specific constructor */
ConstantSizedFifo (uint size);
/* Destructor */
~ConstantSizedFifo ();
/* get the first object */
T *get ();
/* get the first object (non totally blocking)
* return NULL if there is none
*/
T *tryGet ();
/* add an object in the fifo */
void put (T *obj);
/* add an object in the fifo
* never block !!!
*/
int getLength ();
/* is there something inside ? */
bool isNonEmpty ();
};
template <class T>
ConstantSizedFifo<T>::ConstantSizedFifo (uint size) {
this->size = size+1;
tab = new T*[this->size];
in = 0;
out = 0;
mypthread_mutex_init (&lock, NULL);
mypthread_cond_init (&nonEmpty, NULL);
}
template <class T>
ConstantSizedFifo<T>::~ConstantSizedFifo () {
delete [] tab;
mypthread_mutex_destroy (&lock);
mypthread_cond_destroy (&nonEmpty);
}
template <class T>
T *ConstantSizedFifo<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;
}
template <class T>
T *ConstantSizedFifo<T>::tryGet () {
T *tmp = NULL;
mypthread_mutex_lock(&lock);
if (in != out) {
// The stack is not empty
tmp = tab[out];
out = (out + 1) % size;
}
mypthread_mutex_unlock(&lock);
return tmp;
}
template <class T>
void ConstantSizedFifo<T>::put (T *obj) {
mypthread_mutex_lock(&lock);
tab[in] = obj;
if (in == out) {
mypthread_cond_broadcast(&nonEmpty);
}
in = (in + 1) % size;
assert (in != out);
mypthread_mutex_unlock(&lock);
}
template <class T>
int ConstantSizedFifo<T>::getLength () {
int tmp;
mypthread_mutex_lock(&lock);
tmp = (in + size - out) % size;
mypthread_mutex_unlock(&lock);
return tmp;
}
template <class T>
bool ConstantSizedFifo<T>::isNonEmpty () {
mypthread_mutex_lock(&lock);
bool res = (in != out);
mypthread_mutex_unlock(&lock);
return res;
}
#endif // CONSTANTFIFO_H
在这种队列中加入了对变量的上锁与解锁,对变量的同步功能。