高效同步队列的实现--抛砖引玉

// sync_case.h

 

#ifndef SYNC_CASE_UWINB_200810291954
#define SYNC_CASE_UWINB_200810291954

#include <afxmt.h>
#include <iostream>


/*
  利用数组实现循环队列,队空想出队时或队满想入队时会阻塞
  同一时刻只能有一个入队操作,同一时刻只能有一个出队操作
  入队和出队操作可以同时进行,无需同步也不会互相干扰
  模板参数 N 是队列可容纳的最大元素数目
*/

template<class T, int N>
class sync_queue
{
public:
    sync_queue():pos_in(0), pos_out(0), objs_in(N,N), objs_out(0,N)
    {
    }
    /*
    sync_queue(sync_queue const &obj) // 拷贝构造函数
    {
        memcpy(elem, obj.elem, sizeof(obj.elem));
        pos_in = obj.pos_in;
        pos_out = obj.pos_out;
        // 同步对象如何初始化?
    }
    */
protected:
    virtual ~sync_queue() // 通过指针动态访问时需要执行子类的析构函数
    {
        //if ( != NULL) delete
    }
public:
    void push(T const &t)
    {
        static CCriticalSection objcs_in;
        objcs_in.Lock();
        objs_in.Lock();
        elem[pos_in] = t;
        pos_in = next(pos_in);
        objs_out.Unlock();
        objcs_in.Unlock();
    }
   
    T const &pop() // 和push()同时执行时,在队空时可能有误判
    {
        static CCriticalSection objcs_out;
        objcs_out.Lock();
        objs_out.Lock();
        int pos_cur = pos_out;
        pos_out = next(pos_out);
        objs_in.Unlock();
        objcs_out.Unlock();
        return elem[pos_cur];
    }
    /*
    sync_queue &operator=(sync_queue const &obj) // 重载赋值运算符
    {
        if (*this != obj)
        {
            // 没有动态申请资源需要释放
        }
        return *this;
    }
    */
    friend std::ostream &operator<<(std::ostream &out, sync_queue const &obj);
   
private:
    int next(int pos) const // 循环数组中计算下一个偏移位置
    {
        return (pos+1) % (N+1);
    }
   
    T elem[N+1];  // 多加一个占位元素用以区分队空和队满
    int pos_in;   // 待入队偏移
    int pos_out;  // 将出队偏移
    CSemaphore objs_in;     //入队信号量计数,队满时阻塞
    CSemaphore objs_out;    //出队信号量计数,队空时阻塞
};


template<class T, int N>
std::ostream &operator<<(std::ostream &out, sync_queue<T,N> const &obj)
{
    static CCriticalSection objcs_see; // 不同类对象之间也需要同步,确保每次输出的完整性
    static int i=0;
    objcs_see.Lock();
#ifdef _DEBUG
    out<<"{in="<<obj.pos_in<<", out="<<obj.pos_out<<", all=[";
    for (i=0; i<N+1; ++i) out<<obj.elem[i]<<", "; out<<"#]; "<<std::ends;
#else
    out<<'{';
#endif
    // 从出队偏移到入队偏移自左向右输出队列有效值元素序列
    out<<"val=[";
    for (i=obj.pos_out; i!=obj.pos_in; i=obj.next(i)) out<<obj.elem[i]<<", "; out<<"#]}"<<std::flush;
    objcs_see.Unlock();
    return out;
}


#endif // SYNC_CASE_UWINB_200810291954

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值