线程池介绍

        线程池是由服务器预先创建的一组子线程,线程池中的线程数量应该和 CPU 数量差不多。线程池中的所 有子线程都运行着相同的代码。当有新的任务到来时,主线程将通过某种方式选择线程池中的某一个子 线程来为之服务。相比与动态的创建子线程,选择一个已经存在的子线程的代价显然要小得多。

        主线程和所有子线程通过一个共享的工作队列来同步,子线程都睡眠在该工作队列上。当有新的任 务到来时,主线程将任务添加到工作队列中。这将唤醒正在等待任务的子线程,不过只有一个子线 程将获得新任务的”接管权“,它可以从工作队列中取出任务并执行之,而其他子线程将继续睡眠在 工作队列上。

在RTSP项目中的线程池代码理解:

实现ThreadPool线程池类:

成员变量:

std::queue<Task> mTaskQueue;
std::mutex mMtx; // 互斥锁.
std::condition_variable mCon; // 条件变量.

std::vector<MThread> mThreads;
bool mQuit;

成员函数:

static ThreadPool* createNew(int num);
explicit ThreadPool(int num);
~ThreadPool();
void addTask(Task& task);

在服务器启动的时候就要新建好线程组,所以在ThreadPool构造函数的时候就需要createThreads

void ThreadPool::createThreads()
{
    std::unique_lock <std::mutex> lck(mMtx);
    for(auto & mThread : mThreads)
        mThread.start(this);
}

创建好线程组后每个线程都会循环等待任务的到来,一旦任务队列中有任务来的时候就会弹出并进行处理。

void ThreadPool::loop(){

    while(!mQuit){

        std::unique_lock <std::mutex> lck(mMtx);
        if (mTaskQueue.empty()) {
            mCon.wait(lck); 
        }
     

        if(mTaskQueue.empty())
            continue;

        Task task = mTaskQueue.front();
        mTaskQueue.pop();

        task.handle();
    }

}

最后就是如何往任务队列中添加任务:

void ThreadPool::addTask(ThreadPool::Task& task)
{
    std::unique_lock <std::mutex> lck(mMtx);
    mTaskQueue.push(task);
    mCon.notify_one();
}

在RTSP服务器中添加任务就是读取本地的aac和h264文件。

在H264FileMediaSource.cpp文件中,在构造函数时向线程池中添加任务。

在AACFileMediaSource.cpp文件中,在构造函数时向线程池中添加任务。

然后在loop中就会弹出任务并进行对应的处理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值