首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Microsoft VC++ PPL和睡眠

Microsoft VC++ PPL和睡眠
EN

Stack Overflow用户
提问于 2013-03-31 01:38:12
回答 3查看 1.7K关注 0票数 3

根据所使用的睡眠机制,以下程序的运行方式会有所不同。

代码语言:javascript
复制
#include <ppltasks.h>
#include <chrono>
#include <thread>
#include <iostream>
#include <atomic>
#include <windows.h>
using namespace std;
#define MODERN_MAN
int main()
{
    atomic<int> cnt;
    concurrency::task_group tg;
    for (int i =0; i<1000; ++i )
    {
        tg.run([&cnt](){cout << "."; cnt++; 
        #ifdef MODERN_MAN
        this_thread::sleep_for(chrono::seconds(5));
        #else
        Sleep(5000);
        #endif
        });
    }
    tg.wait();
    cout << cnt;
    return 0;
}

不同的是,从我所看到的sleep_for来看,任务的调度方式是1休眠不会阻止其他任务的运行。

从我所看到的Sleep来看,他们阻止了进一步的任务运行。

我的问题是:

a) PPL线程池如何才能巧妙地解决sleep_for问题(我认为这是一个告诉OS的系统调用(将此线程放在非活动线程列表中x秒)

b)我在这里看到的使用sleep_for的行为是有保证的吗(也就是它是否定义了我不会获得与Sleep相同的行为)

EN

回答 3

Stack Overflow用户

发布于 2013-03-31 14:31:45

a) PPL线程池如何才能巧妙地解决sleep_for问题(我认为这是一个系统调用,它告诉OS (将此线程放在非活动线程列表中x秒)

在微软的VC++2012平台上,基于Concurrency Runtime(ConcRT)自带的cooperative and work-stealing scheduler,实现了C++标准线程库和PPL。所以ConcRT调度器可以巧妙地处理包括std::this_thread::sleep_for在内的任务。

b)我在这里看到的行为是使用sleep_for保证的(也就是它是否定义了我不会获得与Sleep相同的行为)

也许不是。Sleep是原生WinAPI,我猜ConRT调度程序不能协同处理它。

附注:微软称Windows7/Server2008 R2 64位版上的ConcRT use User-mode scueduling(UMS)。在这样的平台上,行为可能会改变。

票数 4
EN

Stack Overflow用户

发布于 2013-04-03 18:04:20

看看相关的头文件(即#include <thread>),看看它有什么不同,可能会有所帮助。例如,这是sleep_for()定义:

代码语言:javascript
复制
template<class _Rep, class _Period> inline
void sleep_for(const chrono::duration<_Rep, _Period>& _Rel_time)
{
    // sleep for duration
    stdext::threads::xtime _Tgt = _To_xtime(_Rel_time);
    sleep_until(&_Tgt);
}

,它使用sleep_until()的“绝对时间”重载。

代码语言:javascript
复制
inline void sleep_until(const stdext::threads::xtime *_Abs_time)
{   
    // sleep until _Abs_time
    if (::Concurrency::details::_CurrentScheduler::_Id() != -1)
    {
        stdext::threads::xtime _Now;
        stdext::threads::xtime_get(&_Now, stdext::threads::TIME_UTC);
        ::Concurrency::wait(_Xtime_diff_to_millis2(_Abs_time, &_Now));
        return;
    }
    _Thrd_sleep(_Abs_time);
}

在这里,跟踪停留在CRT对_Thrd_sleep()的调用上,要弄清楚条件代码在做什么并不那么容易。看起来它对一个非默认调度程序采取了不同的操作,但我现在看不出原因。在任何情况下,也许这已经给我们带来了一些启示?

票数 2
EN

Stack Overflow用户

发布于 2013-04-02 20:05:52

其中一个原因可能是两种睡眠方法的准确性不同。为了找出答案,您应该在您的平台上通过测量两个相邻的Sleep(0)和两个相邻的Sleep(1)之间的时间以及sleep_for()的时间来测试准确性

请注意,计时器值的精确度与其实际精确度之间可能存在显著差异。例如,clock()提供毫秒精度,但在我的机器上,其精度(平均)为15ms。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15721455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档