Linux下基于C++的线程应用
Part1-单线程实现任务处理
在Part1讲述的主要是Linux中线程的应用以及在实际开发中需要注意的地方,会以一实例程序进行讲述。
总体代码预览
基于C++实现(C++11)
WorkerThread.h头文件实现
#ifndef WORKERTHREAD_H_
#define WORKERTHREAD_H_
#include <functional>
#include <thread>
#include <condition_variable>
#include <atomic>
namespace threading{
class WorkerThread{
public:
/**
* Construct a worker thread.
*/
WorkerThread();
/*
* Destruct a worker thread.
*/
~WorkerThread();
/**
* Perform work on this worker thread until the work is complete or cancel is called.
*
* @param workFunc the work function, which shall be called repeatedly while the workFunc returns true or until
* cancel() is called.
*/
void run(std::function<bool()> workFunc);
/**
* Cacel currently running work. If work is not running, the call has no effect.
*/
void cancel();
private:
/**
* method for running thread.
*/
void runInternal();
/// Flag indicating the thread is stopping
std::atomic<bool> m_stop;
/// Flag indicating the work should be cancelled
std::atomic<bool> m_cancel;
/// The thread on which to perform work.
std::thread m_thread;
/// The worker function
std::function<bool()> m_workerFunc;
/// Mutex for protecting the condition.
std::mutex m_mutex;
/// Condition variable for waking the thread.
std::condition_variable m_workReady;
};
}// namespace threading
#endif
WorkerThread.cpp的实现
#include <iostream>
#include "WorkerThread.h"
namespace threading{
WorkerThread::WorkerThread() :
m_stop{false},
m_cancel{false} {
m_thread = std::thread{std::bind(&WorkerThread::runInternal,this)};
}
WorkerThread::~WorkerThread(){
m_stop = true;
std::unique_lock<std::mutex> lock(m_mutex);
lock.unlock();
m_workReady.notify_one();
if (m_thread.joinable()) {
m_thread.join();
}
}
void WorkerThread::run(std::function<bool()> workFunc){
std::lock_guard<std::mutex> lock(m_mutex);
m_cancel = false;
m_workerFunc = std::move(workFunc);
m_workReady.notify_one();
}
void WorkerThread::cancel() {
m_cancel = true;
}
void WorkerThread::runInternal(){
std::unique_lock<std::mutex> lock(m_mutex);
do {
while (!m_workerFunc && !m_stop) {
m_workReady.wait(lock);
}
while (!m_stop && !m_cancel && m_workerFunc());
m_workerFunc = nullptr;
} while (!m_stop);
}
}
该例子中所涉及的知识点
C++
- std::mutex
- std::unique_lock
- std::lock_guard
- std::thread
- std::bind
1)std::thread与std::bind的使用
在源文件WorkerThread.cpp中,
构造函数: WorkerThread
WorkerThread::WorkerThread() :
m_stop{false},
m_cancel{false} {
m_thread = std::thread{std::bind(&WorkerThread::runInternal,this)};
}
std::thread是C++标准库用于创建单个线程,有了线程后,程序允许多个函数并行执行. 使用std::thread创建线程成功后会立即执行(这里延迟依赖系统调度的延迟).
注册到std::thread中的函数(callback)与外部通信可以依赖于std::promise(C++11)或者共享变量,当有同步的需要时可以依赖std::mutex(互斥锁)与std::atomic
std::thread{std::bind(&WorkerThread::runInternal,this)};
详细说明:
在这个场景下std::thread主要需要两个参数(不同的构造函数):
template< class Function, class… Args >
explicit thread( Function&& f, Args&&… args );
f - Callable object to execute in the new thread
args… - arguments to pass to the new function
// 引用 https://en.cppreference.com/w/cpp/thread/thread