美文网首页
c++ 线程安全队列

c++ 线程安全队列

作者: mapleSeriesX | 来源:发表于2019-10-28 17:55 被阅读0次

示例

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"FFMPEG",__VA_ARGS__)
SafeQueue<char *> safeQueue;
void * pushData(void *){
    int i=0;
    while(1){
         i++;
        char *d= 0;//另一种方法 char *d= static_cast<char *>(malloc(4 * sizeof(char *))); sprintf(d,"第%d个",i);
         if(asprintf(&d,"第%d个",i)<0){
             return 0;//内存分配失败
         }

        LOGE("存放%s",d);
         safeQueue.push(d);
         usleep(2000*1000);
         free(d);// malloc 动态内存分配 或者是 asprintf传了指针的地址,内部动态分配了内存。 需要手动释放内存。
     } 
}
void * popData(void *){
    char * dd=0;
    while (1){
        usleep(1000*1000);
        safeQueue.pop(dd);
        if(dd!=0){
            LOGE("获取%s",dd);
        } 
    } 
}
void main(){
    pthread_t p1,p2;
    pthread_create(&p1,0,pushData,0);
    pthread_create(&p2,0,popData,0);
}

SafeQueue队列

/**
 * Created by maple on 2019-10-25 16:25
 * E-Mail Address:740917401@qq.com
 */
#ifndef DNRECORDER_SAFE_QUEUE_H
#define DNRECORDER_SAFE_QUEUE_H

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


//todo 宏 开关 是否使用c++11
//#define C11
#ifdef C11
#include <thread>
#endif


using namespace std;

template<typename T>
class SafeQueue {
public:
    SafeQueue() {
#ifdef C11

#else
        pthread_mutex_init(&mutex, NULL);
        pthread_cond_init(&cond, NULL);
#endif

    }

    ~SafeQueue() {
#ifdef C11
#else
        pthread_cond_destroy(&cond);
        pthread_mutex_destroy(&mutex);
#endif

    }

    void push(T new_value) {
#ifdef C11
        //锁 和智能指针shared_ptr原理类似,自动释放
        lock_guard<mutex> lk(mt);
        if (work) {
            q.push(new_value);
            cv.notify_one();
        }
#else
        pthread_mutex_lock(&mutex);
        if (work) {
            q.push(new_value);
            pthread_cond_signal(&cond);//通知写入完成
        }
        pthread_mutex_unlock(&mutex);
#endif

    }


    int pop(T &value) {
        int ret = 0;
#ifdef C11
        //占用空间相对lock_guard 更大一点且相对更慢一点,但是配合条件必须使用它,更灵活
        unique_lock<mutex> lk(mt);
        //第二个参数 lambda表达式:false则不阻塞 往下走
        cv.wait(lk,[this]{return !work || !q.empty();});
        if (!q.empty()) {
            value = q.front();
            q.pop();
            ret = 1;
        }
#else
        pthread_mutex_lock(&mutex);
        //在多核处理器下 由于竞争可能虚假唤醒 包括jdk也说明了 所以用while循环来等待 而不是if
        while (work && q.empty()) {
            pthread_cond_wait(&cond, &mutex);//等待写入
        }
        if (!q.empty()) {
            value = q.front();//把顶部的数据拿出来一个
            q.pop();//把顶部的数据出队一个
            ret = 1;
        }
        pthread_mutex_unlock(&mutex);
#endif
        return ret;
    }

    void setWork(int work) {
#ifdef C11
        lock_guard<mutex> lk(mt);
        this->work = work;
#else
        pthread_mutex_lock(&mutex);
        this->work = work;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
#endif

    }

    int empty() {
        return q.empty();
    }

    int size() {
        return q.size();
    }

    void clear() {
#ifdef C11
        lock_guard<mutex> lk(mt);
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            T value = q.front();
            releaseHandle(value);
            q.pop();
        }
#else
        pthread_mutex_lock(&mutex);
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            T value = q.front();
            q.pop();
        }
        pthread_mutex_unlock(&mutex);
#endif

    }


private:

#ifdef C11
    mutex mt;
    condition_variable cv;
#else
    pthread_cond_t cond;
    pthread_mutex_t mutex;
#endif

    queue<T> q;
    //是否工作的标记 1 :工作 0:不接受数据 不工作
    int work;
};


#endif //DNRECORDER_SAFE_QUEUE_H


相关文章

  • c++ 实现 blocking queue

    阻塞队列就是多线程线程安全的队列,在多线程场景下经常用到,c++ 标准库里面没有提供阻塞队列,boost 中有提供...

  • C++ 实现线程池

    c++实现一个线程池,首先需要有两个数据结构,一个是线程池,一个是任务队列。为了每个线程线程安全的从任务队列里面拿...

  • c++ 线程安全队列

    示例 SafeQueue队列

  • ProiorityBlockingQueue

    优先级队列,线程安全队列。java output

  • GCD线程安全

    译自官方文档 分发队列与线程安全 在分发队列的环境中谈论线程安全显得有些奇怪,但是线程安全仍然是与其相关的话题。任...

  • SDWebImage扩展笔记(一)

    SDWebImage中使用GCD主线程队列 GCD 如何安全获取主线程队列 获取主线程是 dispatch_get...

  • GCD

    GCD 队列与线程的关系 主队列和主线程 『ios』主线程 和 主队列的关系,绝对安全的UI操作,主线程中一定是主...

  • java源码-ArrayBlockingQueue

    开篇  ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列。 线程安全是指ArrayBloc...

  • Disruptor笔记

    Java自带的线程安全队列 介绍Disruptor之前,我们先来看一看常用的线程安全的内置队列有什么问题。Java...

  • Python collections模块--deque

    deque 线程安全的双向队列 append(x) 在队列的右边添加 x appendleft(x) 在队列的左...

网友评论

      本文标题:c++ 线程安全队列

      本文链接:https://www.haomeiwen.com/subject/uxebvctx.html