while(true) {
if(pool.try_get_work()) {
// do work
}
else {
std::this_thread::yield(); // other threads can push work to the queue now
}
}
std::this_thread::yield() 的目的是避免一个线程(that should be used in a case where you are in a busy waiting state)频繁与其他线程争抢CPU时间片, 从而导致多线程处理性能下降.
std::this_thread::yield() 是让当前线程让渡出自己的CPU时间片(给其他线程使用)
std::this_thread::sleep_for() 是让当前休眠”指定的一段”时间.
sleep_for()也可以起到 std::this_thread::yield()相似的作用, (即:当前线程在休眠期间, 自然不会与其他线程争抢CPU时间片)但两者的使用目的是大不相同的:
std::this_thread::yield() 是让线程让渡出自己的CPU时间片(给其他线程使用)
sleep_for() 是线程根据某种需要, 需要等待若干时间.
一、线程库(thread)
C++11中线程较轻量级,线程的创建和执行的消耗较小,但是同时C++中线程没有明确的状态信息,如果不怕麻烦可以直接使用linux下的posix线程库,这对底层开发者还是很有用的。
**c++标准线程库是c++11/14/17才支持的,很多编译器的版本还并没有完全支持他们的标准
c++11线程特点:
1. thread创建后,C++始终尝试在一个新线程中执行任务,如果失败返回std::system_error
2. 没有线程运行结果的接口,无法获得执行结果。(后面会讨论其他方法)
3. 如果有异常在thread中发生,并且没有被捕获,std::terminate将会被调用
4. 只能调用join去结束线程,或者detach去转成后台线程执行。否则当thread被析构时,程序会被abort。
5. 如果线程detach并且main函数执行结束,所有的detach线程会被终止.
6. 线程只可以通过std::move转移,不可以复制。
1. 通过全局函数创建线程
线程类的构造函数是变参构造函数,第一个参数是线程函数,后面的参数为线程函数的参数(参数通过值传递方式,若要引用传递须加std::ref())。
#include <thread>
#include <iostream>
void hello(int i)
{
std::cout << "Hello from thread :" << i<<std::endl;
}
int main()
{
std::thread t1(hello,1);
t1.join();
return 0;
}
2. 通过仿函数创建线程
//class Counter 实现 operator()
//1) thread t1{Counter(1, 20)}; //c++统一推荐方法
//2) Counter c(1, 20);
// thread t2(c);
//3) thread t3(Counter(1,20));
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class thread_c
{
public:
void operator () ()
{
cout << "hello from class member function" << endl;
}
private:
};
int main()
{
thread_c c;
thread t(c);
//thread t1{thread_c()};
this_thread::sleep_for(chrono::seconds(1));
return 0;
}
thread t3(Counter());是不行的,因为编译器会认为你在声明一个函数,函数名为t3,此时只能用第一种构造方式。
3. 通过lambda表达式创建线程
#include <thread>
#include <iostream>
#include <vector>
int main()
{
std::vector<std::thread> threads;
for(int i = 0; i < 5; ++i)
{
threads.push_back(std::thread([]()
{
std::cout << std::this_thread::get_id() << std::endl;
}
));
}
for(auto& thread : threads)
{
thread.join();
}
return 0;
}