简单的辅助线程
辅助线程为您提供并行处理能力
引言
有时,我们需要一个额外的线程来并行执行任务,或者只是为了解除主线程的阻塞。为了获得更好的性能,我们不希望每次都创建一个新线程。此外,我们需要对线程进行更多的控制。 在本文中,我们将实现一个具有以下功能的线程。
- 您无需定义线程过程,而是可以使用 lambda 提交任何函数
- 完全用 C++11 实现,兼容任何操作系统
- 提交一个异步执行的任务
- 提交一个同步执行的任务(但在工作线程上)
- 自动等待任务完成
- 实现大量使用 C++ 11(线程、lambda、条件变量)
Using the Code
下面的示例代码列出了工作线程的用法
#include <iostream>
#include <chrono>
#include <thread>
#include "workerthread.h"
int main()
{
std::cout << "Hi, Welcome to demo of worker thread" << std::endl;
{
// Create two worker threads
WorkerThread thread;
WorkerThread thread2;
// Example of a synchronous task
thread.doSync([]{ std::cout << "First - blocking call" << std::endl; });
for (int i = 1; i < 100; i++)
{
auto& t = i % 2 == 0 ? thread : thread2;
if (i == 10) // Another synchronous task in between
{
thread.doSync([]{
std::cout << "Second - blocking call" << std::endl; });
}
// Multiple asynchronous tasks queued
t.doAsync([i]
{
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(200));
std::cout << (i % 2 == 0 ? "thread-" : "thread2-")
<< "iteration number: " << i << std::endl;
});
}
thread.doSync([]{ std::cout << "Last - blocking call"; });
}// Added extra scope to demo destruction of worker thread
std::cout << "This must be last line\n";
}
工作线程的实现
- 使用 C++ 函数构造来存储提交的任务
- 完成当前队列并等待新工作的信号
void WorkerThread::startThread()
{
std::unique_lock<std::mutex> l(mutex);
do
{
while (isRunning && tasks.empty())
itemInQueue.wait(l);
while (!tasks.empty())
{
auto size = tasks.size();
printf("Number of pending task are %d\n", size);
const std::function<void()> t = tasks.front();
tasks.pop_front();
l.unlock();
t();
l.lock();
}
itemInQueue.notify_all();
} while (isRunning);
itemInQueue.notify_all();
}
异步任务只是被排队,调用线程不会被阻塞
void WorkerThread::doAsync(const std::function<void()>& t)
{
std::lock_guard<std::mutex> _(mutex);
tasks.push_back(t);
itemInQueue.notify_one();
}
同步任务稍微复杂一些,我们需要阻塞调用线程,直到在提交的任务之前的所有任务都已排队并且提交的任务完成。
void WorkerThread::doSync(const std::function<void()>& t)
{
std::condition_variable event;
bool finished = false;
std::unique_lock<std::mutex> l(mutex);
auto lambda = [this, &t, &finished, &event]
{
t();
std::lock_guard<std::mutex> l(mutex);
finished = true;
event.notify_one();
};
tasks.push_back(lambda);
itemInQueue.notify_one();
while (!finished)
event.wait(l);
}
通过少量修改,此类可以用于采用基于优先级的任务。