基于条件变量的消息队列 说明介绍_C 语言

条件变量是线程之前同步的另一种机制。条件变量给多线程提供了一种会和的场所。当条件变量和互斥锁一起使用时,允许线程以无竞争的方式等待特定的条件发生。这样大大减少了锁竞争引起的线程调度和线程等待。

     消息队列是服务器端开发过程中绕不开的一道坎,前面,我已经实现了一个基于互斥锁和三队列的消息队列,性能很不错。博客园中的其他园主也实现了很多基于环形队列和lock-free的消息队列,很不错,今天我们将要实现一个基于双缓冲、互斥锁和条件变量的消息队列;这个大概也参考了一下java的blockingqueue,在前面一个博客中有简单介绍!!基于三缓冲的队列,虽然最大限度上解除了线程竞争,但是在玩家很少,消息很小的时候,需要添加一些buff去填充数据,这大概也是其一个缺陷吧!

     消息队列在服务器开发过程中主要用于什么对象呢?

     1: 我想大概就是通信层和逻辑层之间的交互,通信层接受到的网络数据,验证封包之后,通过消息队列传递给逻辑层,逻辑层将处理结果封包再传递给通信层!

     2:逻辑线程和数据库IO线程的分离;数据库IO线程负责对数据库的读写更新,逻辑层对数据库的操作,封装成消息去请求数据库IO线程,数据库IO线程处理完之后,再交回给逻辑层。

     3:日志;处理模式与方式2 类似。不过日志大概是不需要返回的!

给出源代码:

BlockingQueue.h文件

复制代码 代码如下:

/*
 * BlockingQueue.h
 *
 *  Created on: Apr 19, 2013
 *      Author: archy_yu
 */

#ifndef BLOCKINGQUEUE_H_
#define BLOCKINGQUEUE_H_

#include <queue>
#include <pthread.h>

typedef void* CommonItem;

class BlockingQueue
{
public:
    BlockingQueue();

    virtual ~BlockingQueue();

    int peek(CommonItem &item);

    int append(CommonItem item);

private:

    pthread_mutex_t _mutex;

    pthread_cond_t _cond;

    std::queue<CommonItem> _read_queue;

    std::queue<CommonItem> _write_queue;

};

 
#endif /* BLOCKINGQUEUE_H_ */

BlockingQueue.cpp 文件代码

复制代码 代码如下:

/*
 * BlockingQueue.cpp
 *
 *  Created on: Apr 19, 2013
 *      Author: archy_yu
 */

#include "BlockingQueue.h"

BlockingQueue::BlockingQueue()
{
    pthread_mutex_init(&this->_mutex,NULL);
    pthread_cond_init(&this->_cond,NULL);
}

BlockingQueue::~BlockingQueue()
{
    pthread_mutex_destroy(&this->_mutex);
    pthread_cond_destroy(&this->_cond);
}

int BlockingQueue::peek(CommonItem &item)
{

    if( !this->_read_queue.empty() )
    {
        item = this->_read_queue.front();
        this->_read_queue.pop();
    }
    else
    {
        pthread_mutex_lock(&this->_mutex);

        while(this->_write_queue.empty())
        {
            pthread_cond_wait(&this->_cond,&this->_mutex);
        }

        while(!this->_write_queue.empty())
        {
            this->_read_queue.push(this->_write_queue.front());
            this->_write_queue.pop();
        }

        pthread_mutex_unlock(&this->_mutex);
    }

 
    return 0;
}

int BlockingQueue::append(CommonItem item)
{
    pthread_mutex_lock(&this->_mutex);
    this->_write_queue.push(item);
    pthread_cond_signal(&this->_cond);
    pthread_mutex_unlock(&this->_mutex);
    return 0;
}

测试代码:

复制代码 代码如下:

BlockingQueue _queue;

void* process(void* arg)
{

    int i=0;
    while(true)
    {
        int *j = new int();
        *j = i;
        _queue.append((void *)j);
        i ++;
    }
    return NULL;
}

int main(int argc,char** argv)
{
    pthread_t pid;
    pthread_create(&pid,0,process,0);

    long long int start = get_os_system_time();
    int i = 0;
    while(true)
    {
        int* j = NULL;
        _queue.peek((void* &)j);

        i ++;

        if(j != NULL && (*j) == 100000)
        {
            long long int end = get_os_system_time();
            printf("consume %d\n",end - start);
            break;
        }
    }

    return 0;
}

时间: 2024-09-17 14:59:33

基于条件变量的消息队列 说明介绍_C 语言的相关文章

基于条件变量的消息队列

     条件变量是线程之前同步的另一种机制.条件变量给多线程提供了一种会和的场所.当条件变量和互斥锁一起使用时,允许线程以无竞争的方式等待特定的条件发生.这样大大减少了锁竞争引起的线程调度和线程等待.      消息队列是服务器端开发过程中绕不开的一道坎,前面,我已经实现了一个基于互斥锁和三队列的消息队列,性能很不错.博客园中的其他园主也实现了很多基于环形队列和lock-free的消息队列,很不错,今天我们将要实现一个基于双缓冲.互斥锁和条件变量的消息队列:这个大概也参考了一下java的blo

实现posix消息队列示例分享_C 语言

mqueue.h 复制代码 代码如下: ////  mqueue.h//  UNIX_C////  Created by 周凯 on 14-2-9.//  Copyright (c) 2014年 zk. All rights reserved.// #ifndef __PS_MQUEUE_H#define __PS_MQUEUE_H #include <unistd.h>#include <sys/types.h> typedef struct mq_info     *mqd_t

C++开发:为什么多线程读写shared_ptr要加锁的详细介绍_C 语言

我在<Linux 多线程服务端编程:使用 muduo C++ 网络库>第 1.9 节"再论 shared_ptr 的线程安全"中写道: (shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化.根据文档(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety), shared_ptr 的线程

KiteQ —— 基于 go + protobuff 的消息队列

KiteQ 是一个基于 go + protobuff 实现的多种持久化方案的 mq 框架(消息队列). 特性: * 基于zk维护发送方.订阅方.broker订阅发送关系.支持水平.垂直方面的扩展 * 基于与topic以及第二级messageType订阅消息 * 基于mysql.文件存储方式多重持久层消息存储 * 保证可靠异步投递 * 支持两阶段提交分布式事务 工程结构: kiteq/ ├── README.md ├── binding 订阅关系管理处理跟ZK的交互 ├── build.sh 安装

Windows窗口消息实例详解_C 语言

本文实例总结了Windows窗口消息.分享给大家供大家参考.具体如下: 复制代码 代码如下: //////////////////////////////////////////////////////////////////////////    #include "AFXPRIV.H"//消息值的定义来源    #include "Dde.h"//DDE消息值的定义来源    #include "CPL.H"//控制面板消息值的定义来源   

C/C++回调函数介绍_C 语言

对于很多初学者来说,往往觉得回调函数很神秘,很想知道回调函数的工作原理.本文将要解释什么是回调函数.它们有什么好处.为什么要使用它们等等问题,在开始之前,假设你已经熟知了函数指针. 什么是回调函数? 简而言之,回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数. 为什么要使用回调函数? 因为可以把调用者与被调用者分开.调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型.某些限制

C++队列用法实例_C 语言

本文实例讲述了C++队列用法.分享给大家供大家参考.具体如下: /* 队列使用时必须包含头文件 #include <queue> 有以下几种方法 入队push(),出队pop(), 读取队首元素front(),读取队尾元素back() , 判断队是否有元素empty() 求队列元素个数size() */ #include <iostream> #include <queue> using namespace std; int main() { queue<int&

基于对话框程序中让对话框捕获WM_KEYDOWN消息的实现方法_C 语言

在对话框程序中,我们经常是利用对话框上的子控件进行命令响应来处理一些事件.如果我们想要让对话框(子控件的父窗口)类来响应我们的按键消息,我们可以通过ClassWizard对WM_KEYDOWN消息进行响应,当程序运行后,我们按下键盘上的按键,但对话框不会有任何的反应.这是因为在对话框程序中,某些特定的消息,例如按键消息,它们被Windows内部的对话框过程处理了(即在基类中完成了处理,有兴趣的读者可以查看MFC的源代码),或者被发送给子控件进行处理,所以我们在对话框类中就捕获不到按键的消息了.

基于Turbo C(V2.0)编译错误信息的详细介绍_C 语言

说明:Turbo C 的源程序错误分为三种类型:致命错误.一般错误和警告.其中,致命错误通常是内部编译出错:一般错误指程序的语法错误.磁盘或内存存取错误或命令行错误等:警告则只是指出一些得怀疑的情况,它并不防止编译的进行. 下面按字母顺序A-Z分别列出致命错误及一般错误信息,英汉对照及处理方法: (一).致命错误英汉对照及处理方法: A-B致命错误 Bad call of in-line function (内部函数非法调用)分析与处理:在使用一个宏定义的内部函数时,没能正确调用.一个内部函数以