在stackoverflow 中,对于yield的解释:std::this_thread::yield tells the implementation to reschedule the execution of threads,
that should be used in a case where you are in a busy waiting state, like in a thread pool:
std::this_thread::sleep_for can be used if you really want to wait for a specific amount of time.
This can be used for task, where timing really matters, e.g.: if you really only want to wait for
2 seconds. (Note that the implementation might wait longer than the given time duration)
yield函数时c++11的新特性,它在std::this_thread::yield命名空间中实现,函数声明如下:
void yield() noexcept;
该函数的功能是让当前线程放弃争夺cpu资源,让操作系统调度进行其他操作。如果在线程运行中,需要不断地判断成立条件,会严重消耗cpu的资源,为了防止循环判断影响cpu的资源,可以判断一次操作是否完成,如果没有完成就调用yield交出时间片,过一会儿再来判断是否完成,这样这个线程占用CPU时间会大大减少。
while(!isDone()); // Bad
while(!isDone()) yield(); // Good
个人理解:
(1) std::this_thread::yield(); 是将当前线程所抢到的CPU”时间片A”让渡给其他线程(其他线程会争抢”时间片A”,
注意: 此时”当前线程”不参与争抢).
等到其他线程使用完”时间片A”后, 再由操作系统调度, 当前线程再和其他线程一起开始抢CPU时间片.
(2) 如果将 std::this_thread::yield();上述语句修改为: return; ,则将未使用完的CPU”时间片A”还给操作系统, 再由操作系统调度, 当前线程和其他线程一起开始抢CPU时间片.
std::this_thread::yield(): 适合应用在 — “that should be used in a case where you are in a busy waiting state”, 如果存在此情况, 线程实际的执行代码类似如下:
void thread_func()
{
while (1)
{
if (!HasTask())
{
return;
}
// else
// {
// // do work
// }
}
}
因为条件不满足, 所以此线程很快就返回(然后立即与其他线程竞争CPU时间片), 结果就是此线程频繁的与其他线程争抢CPU时间片, 从而影响程序性能,使用 std::this_thread::yield() 后, 就相当于”当前线程”检查条件不成功后, 将其未使用完的”CPU时间片”分享给其他线程使用, 等到其他线程用完后, 再和其他线程一起竞争.
结论:
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() 是线程根据某种需要, 需要等待若干时间.
#include "stdafx.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
std::mutex g_mutex;
std::atomic<bool> ready(false);
void count1m(int id)
{
while (!ready)// wait until main() sets ready...
{
//若线程还有没创建的,将当前线程分配的cpu时间片,让调度器安排给其他线程,
//由于使用了yield函数,在 not Ready 情况下,避免了空循环,在一定程度上,可以提高cpu的利用率
std::this_thread::yield();
}
for ( int i = 0; i < 1000000; ++i) {}
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "thread : "<< id << std::endl;
}
int main()
{
std::thread threads[10];
std::cout << "race of 10 threads that count to 1 million:\n";
for (int i = 0; i < 10; ++i)
{
threads[i] = std::thread(count1m, i);
}
ready = true; // go!
for (auto& th : threads)
{
th.join();
}
std::cout << '\n';
return 0;
}