检测操作系统版本并相应地选择线程函数

发布于 2024-11-15 11:32:55 字数 467 浏览 0 评论 0原文

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

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

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

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

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

Is there a good way to check for OS version (in this case Windows Vista+ or not) and decide at runtime what version of a function is going to be used.

Concretely I am talking about implementing pthreads in Win32 threads. In my ideal case, the pthreads library would determine at program startup which OS is running. If it is Vista+, all function calls will be redirected to the cool new and fast functions, otherwise, the old emulation layer will be used.

So in effect, the library will have two version of each function, one new and one old. And a one-time runtime check would determine at runtime, before the program enters main so to speak, which version it's going to use. I know there's libraries that detect CPU features like SSE at runtime, and use the relevant functions, but I think they check at each function call. That would be too expensive to do in a low-level threading library IMO.

Is this possible? Can function calls be "relinked"/redirected at runtime so speak?

EDIT: crazy things like custom crt startup code would be possible for this (I'm talking about winpthreads for mingw-w64, which provides its own startup code)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无声无音无过去 2024-11-22 11:32:55

简单的答案是什么?为您的图书馆定义并构建调度表/结构。像这样的东西:

// 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 );
}

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

玩得开心!

The simple answer? Define and build a dispatch table/structure for your library. Something like this:

// 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;

Next, your library's initialize function should contain something like this:

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

Finally, your libraries exported functions should look something like this:

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

Naturally, you'll need to ensure that your modern implementations utilize runtime binding for exports that don't exist on legacy platforms.

Have fun!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文