<pthread.h>与<thread>都是多线程的库函数,这里介绍的是c++11的<thread>的函数。
1. 线程
本质是函数,可用lambda表达式初始化。这里函数不会执行,而是作为对象传递。
std::vector<std::thread> workers;
workers.emplace_back(
[this, number_of_cpus, if_set_highest_priority]
{...});
2. 线程池
目的:管理多个线程,不然很可能反复的:想解决一个任务-创建一个线程-解决-销毁线程,浪费时间。
组件:任务队列,线程组(workers),并配合锁和条件变量。
3. 互斥锁
目的:以queue为例,一边pop一边push会有问题。
-
std::mutex
: lockable object, 用于阻止多个线程访问同时访问一段代码。
mtx.lock(), mtx.unlock() -
std::unique_lock
: 管理mutex的状态。
构造后,给mutex上锁,析构后自动unlock。如果mutex已经是锁着的,试图上锁时,当前线程会被阻塞直到mutex不锁。 -
std::lock_guard
:和上个类似,区别是上个可以中途unlock()与lock(),而这个全程都是lock的状态。
4. 条件变量 condition variable
目的:实现同步机制,且避免空循环。以“一边向queue push,一边从queue中读取”为例,如果queue空了,就不要频繁读取了,而是等到queue非空了再去唤醒。
想使用condition_variable,则需配套使用wait,wait_until,wait_for
。
-
std::condition_variable::wait
:
通过unique_lock的引用控制阻塞与否。
参数只有unique_lock时,另lock.unlock(),等待;notify()时唤醒cv,lock.lock(),开始执行。
参数有两个(unique_lock, prediction)时,prediction为true则可通过。为false则等待,lock.unlock();直到notify()时唤醒,lock.lock(),开始执行。
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock, //wj: function only blocks if pred returns false
[this]
{ return this->stop || !this->tasks.empty(); });
if (this->stop && this->tasks.empty())
return;
task = std::move(this->tasks.front());
printf("\ntask from Thread_id [%ld] set CPU-%d affinity success.\r\n",get_thread_id(),cpu_id);
this->tasks.pop();
}