【问题标题】:Detecting OS version and choosing threading functions accordingly检测操作系统版本并相应地选择线程函数
【发布时间】:2011-06-13 16:23:03
【问题描述】:

是否有一种检查操作系统版本的好方法(在本例中为 Windows Vista+ 或否)并在运行时决定将使用哪个版本的函数。

具体来说,我说的是在 Win32 线程中实现 pthread。在我的理想情况下,pthreads 库将在程序启动时确定正在运行的操作系统。如果是Vista+,所有函数调用都会被重定向到酷炫的新快速函数,否则会使用旧的仿真层。

因此,库实际上将有每个函数的两个版本,一个新版本和一个旧版本。 一次性运行时检查将在运行时确定,在程序进入 main 之前,可以说,它将使用哪个版本。我知道有一些库可以在运行时检测 SSE 等 CPU 特性,并使用相关函数,但我认为它们会在每个函数调用时进行检查。在低级线程库 IMO 中这样做太昂贵了。

这可能吗?函数调用可以在运行时“重新链接”/重定向吗?

编辑:像自定义 crt 启动代码这样疯狂的事情是可能的(我说的是 mingw-w64 的 winpthreads,它提供了自己的启动代码)

【问题讨论】:

  • 参见this question 并将您的库的两个版本放在不同的 DLL 中,然后让第三个 stump DLL(或静态库)决定在其初始化函数中加载哪个版本。
  • @larsmans:好的,有静态库的类似物吗?
  • @ruvenvb:您可以在初始化函数中检查操作系统版本是什么,然后为您的线程原语构造适当的调度表,并根据这些实现库的其余部分。开销类似于 C++ 中动态多态性 (virtual) 的开销,但客户端必须调用初始化程序。
  • 与测试 Windows 版本相比,通常最好检查是否存在所需的 API,例如通过调用 GetProcAddress 来查看特定函数是否存在。
  • @David:除了那些将新行为添加到现有 API 的不幸情况。

标签: c windows runtime


【解决方案1】:

简单的答案?为您的库定义和构建调度表/结构。像这样的:

// Define function pointers and dispatch structure.
typedef void( *PFN_pthread_exit )( void *value_ptr );
typedef struct tag_PTHREAD_IMPL
{
    PFN_pthread_create ptr_pthread_exit;
    // Add the rest rest here.
} PTHREAD_IMPL;

// Define your various implementations dispatcher structures.
static PTHREAD_IMPL legacy_impl = { 
    &legacy_pthread_exit_impl
};
static PTHREAD_IMPL latest_andgreatest_impl = { 
    &pthread_exit_impl
};
static PTHREAD_IMPL* s_pImpl = NULL;

接下来,您的库的初始化函数应该包含如下内容:

int StaticInitialize( )
{
    // Initalize dispatcher
    if( latest and greatest OS version )
        s_pImpl = &latest_andgreatest_impl
    else
        s_pImpl = &legacy_impl;
}

最后,您的库导出函数应该如下所示:

int pthread_exit( void *value_ptr )
{
    ASSERT( s_pImpl );
    ASSERT( s_pImpl->ptr_pthread_exit );
    return s_pImpl->ptr_pthread_exit( value_ptr );
}

当然,您需要确保您的现代实现将运行时绑定用于旧平台上不存在的导出。

玩得开心!

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2013-02-02
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多