封装pthread库的几个类(5)-创建一个简单的同步队列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zeqi1991/article/details/82561091

同步队列

#ifndef __INCLUDE_SYNC_QUEUE_H__
#define __INCLUDE_SYNC_QUEUE_H__

#include "condition.h"
#include "mutex_lock.h"
#include "mutex_lock_guard.h"

#include <list>
#include <type_traits>
#include <utility>

template <typename T>
class SyncQueue
{
public:
    SyncQueue(unsigned int max_size) : not_empty_(mutex_),
                                             not_full_(mutex_),
                                             max_size_(max_size),
                                             need_stop_(false)
    {

    }

    ~SyncQueue()
    {

    }

    void Put(const T& x)
    {
        Add(x);
    }

    void Put(T &&x)
    {
        Add(x);
    }

    void Take(T &x)
    {
        MutexLockGuard locker(mutex_);
        while (!need_stop_ && IsEmpty())
        {
            not_empty_.Wait();
        }
        if (need_stop_)
            return;
        x = queue_.front();
        queue_.pop_front();
        not_full_.Notify();
    }

    void Take(std::list<T>& x)
    {
        MutexLockGuard locker(mutex_);
        while (!need_stop_ && IsEmpty())
        {
            not_empty_.Wait();
        }
        if (need_stop_)
            return;
        x = std::move(queue_);
        not_full_.Wait();
    }

    void Stop()
    {
        {
            MutexLockGuard locker(mutex_);
            need_stop_ = true;
        }
        not_empty_.NotifyAll();
        not_full_.NotifyAll();
    }

    bool Empty()
    {
        MutexLockGuard locker(mutex_);
        return queue_.empty();
    }

    bool Full()
    {
        MutexLockGuard locker(mutex_);
        return queue_.size() >= max_size_;
    }

    size_t GetSize()
    {
        MutexLockGuard locker(mutex_);
        return queue_.size();
    }

private:
    size_t GetCount()
    {
        return queue_.size();
    }

    bool IsFull() const
    {
        return queue_.size() >= max_size_;
    }

    bool IsEmpty() const
    {
        return queue_.empty();
    }

    template <typename F>
    void Add(F &&x)
    {
        MutexLockGuard locker(mutex_);
        while (!need_stop_ && IsFull())
            not_full_.Wait();
        if (need_stop_)
            return;
        queue_.push_back(std::forward<F>(x));
        not_empty_.Notify();
    }

private:
    //缓冲区对象
    std::list<T> queue_;
    //mutex
    MutexLock mutex_;
    //非空条件
    Condition not_empty_;
    //不满的条件
    Condition not_full_;
    //缓冲区最大size
    unsigned int max_size_;
    //停止的标志
    bool need_stop_;
};

#endif //__INCLUDE_SYNC_QUEUE_H__

简单的测试代码:

#include <iostream>
#include <functional>
#include <sys/syscall.h>
#include <unistd.h>

#include "sync_queue.h"

using namespace std;

pid_t GetCurrentThreadId()
{
    return (pid_t)(syscall(__NR_gettid));
}


typedef std::function<void()> T;

SyncQueue<T> g_queue(200);

void* Thread_Func(void* arg)
{
    pid_t thread_id = GetCurrentThreadId();
    for (int i = 0; i < 20; i++)
    {
        T x = [thread_id](){
            std::cout << "在线程id = " << thread_id << "中在处理数据!" << std::endl;
        };
        g_queue.Put(x);
        sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t pid1, pid2, pid3, pid4;
    pthread_create(&pid1, NULL, Thread_Func, NULL);
    pthread_create(&pid2, NULL, Thread_Func, NULL);
    pthread_create(&pid3, NULL, Thread_Func, NULL);
    pthread_create(&pid4, NULL, Thread_Func, NULL);
    // pthread_join(pid1, NULL);
    // pthread_join(pid2, NULL);
    // pthread_join(pid3, NULL);
    // pthread_join(pid4, NULL);
    while (1)
    {
        T x;
        g_queue.Take(x);
        x();
    }

    return 0;
}

测试结果:
这里写图片描述

有了同步队列后,可以写一个简单的线程池了,这个线程池只是很初级的一个,后续可以添加多中功能,比如根据空闲线程数量和忙碌线程数量比值来控制线程池的线程数量等等。

猜你喜欢

转载自blog.csdn.net/zeqi1991/article/details/82561091
今日推荐