gpt4 book ai didi

c++ - 获取 PostThreadMessage 的 boost::thread 的 ID

转载 作者:可可西里 更新时间:2023-11-01 13:30:24 24 4
gpt4 key购买 nike

我有一个使用 Boost 1.47.0 的 Visual Studio 2008 C++ 项目,我需要在其中获取 boost::thread 的 native Windows ID 以传递给 PostThreadMessage。

在 Windows Vista 和 7 中,我会这样做:

DWORD thread_id = ::GetThreadId( mythread.native_handle() );

这很好,但我还需要我的应用程序在 GetThreadId 不存在的 XP 中运行。

我发现 boost:thread 将线程 ID 值存储在 boost::thread::id 的私有(private)数据成员 thread_data 中。我可以通过做一些令人讨厌的转换来实现这一点:

boost::detail::thread_data_base* tdb = *reinterpret_cast< boost::detail::thread_data_base** >( &message_thread.get_id() );
DWORD thread_id = tdb->id;

但是,我开始收到有关引用临时 boost::thread::id 对象的编译器警告。

warning C4238: nonstandard extension used : class rvalue used as lvalue

有没有什么好的方法来获取ID?看到我需要的数据,但无法获取它,这非常令人沮丧。

谢谢,保罗H

最佳答案

这是一个聪明/讨厌的黑客,使用 Johannes Schaub - litb 描述的技术在他的博客上,Access to private members: Safer nastiness .所有功劳都应归功于约翰内斯。我将承担将其应用于现实场景的责任(或者你可以):

#include <windows.h>
#include <iostream>

#include "boost/thread.hpp"

using namespace std;


// technique for accessing private class members
//
// from: http://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.html
//

template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};

struct thread_data_f {
typedef unsigned boost::detail::thread_data_base::*type;

friend type get(thread_data_f);
};

struct thread_id_f {
typedef boost::detail::thread_data_ptr boost::thread::id::*type;

friend type get(thread_id_f);
};

template struct Rob<thread_data_f, &boost::detail::thread_data_base::id>;
template struct Rob<thread_id_f, &boost::thread::id::thread_data>;

unsigned int get_native_thread_id( boost::thread const& t)
{
boost::detail::thread_data_ptr thread_data = t.get_id().*get(thread_id_f());
unsigned thread_id = (*thread_data).*get(thread_data_f());

return thread_id;
}

//
//
//


// test of get_native_thread_id()


void thread_func()
{
cout << "thread running..." << endl;

cout << "Windows says my ID is: " << GetCurrentThreadId() << endl;

for (;;) {
boost::this_thread::yield();
}
}


int main()
{
boost::thread t(thread_func);

::Sleep(2000);

cout << "boost says my thread ID is: " << get_native_thread_id(t) << endl;

return 0;
}

我不确定这是否是获取信息的“好方法”。但它可以在不修改 boost 头文件或库的情况下工作,并且编译器根本不会提示——即使有相对较高的警告。测试于:

  • MinGW 4.6.1 -Wall -Wextra 关闭了一些特别嘈杂的警告 - 但不是特别针对此测试。它们在我的通用“编译此测试”脚本中已关闭。
  • VC++ 2008 和 2010,带有/W4

这是一个显示它有效的示例运行:

C:\temp>test
thread running...
Windows says my ID is: 5388
boost says my thread ID is: 5388

当然,不用说,如果/当 boost::thread 随着时间的推移发生变化时,这可能会中断,但可能不会悄无声息。


一些解释性说明/提示:

此技术中使用的“漏洞”在 C++03 14.7.2/8“显式实例化”中:

The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible.]

Dave Abrahams 有一个“要点”,它使用类似的技术以及很好地解释正在发生的事情的注释:

我发现他在 Johannes 博客上一篇关于私有(private)成员访问的文章中留下的评论:Access to private members. That's easy!

关于c++ - 获取 PostThreadMessage 的 boost::thread 的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9473719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com