1. boost::thread::id 的基础知识

boost::thread::id 的对象能够用来标识线程,每个正在运行的线程都可以获取一个唯一可用的线程id,可以通过调用 boost::thread 的成员函数 get_id(),或者通过在线程中调用 boost:this_thread::get_id()

boost::thread::id 可以被复制, 可以被用作与之关联容器的标识。线程 id 提供了各种比较操作符,线程id 也可以通过输出流的输出操作符输出(虽然其输出格式没有规定)。

③ 一个 boost::thread::id 要么指向一个线程,要么不指向任何线程,即 Not-any-Thread 。注意所有 Not-any-Thread 的线程 id 都是相等的。
参考链接:boost 线程管理

2. 程序实例
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

using namespace boost;

void thread2(int x){
	std::cout << "x= " << x << std::endl;
	for (int i = 0; i < 10
		; i++){
		std::cout << "thread2: " << i << std::endl;
	}
}

int main(){
	std::cout << "Current thread id: " << boost::this_thread::get_id()<< std::endl;
	boost::thread thrd2(boost::bind(&thread2, 2));
	std::cout << "thrd2 的线程ID:" << thrd2.get_id() << std::endl;
	if (thrd2.joinable()){
		thrd2.join();
		std::cout << "thrd2 的线程ID:" << thrd2.get_id()<<std::endl;
	}
	if (!thrd2.joinable()){
		std::cout << "thrd2 is unjoinable" << std::endl;
	}
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	
	return 0;
}

运行结果:
在这里插入图片描述
根据运行结果可知:当线程被join之后,就没有了线程id

参考链接: This Thread

3. 将boost::thread::id转化为DWORD类型(有些问题,一直未解决)

想要通过获取线程ID,然后使用PostMessage()PeekMessage()进行线程间通信,关键问题是他们需要的线程ID是DWORD类型。如何将boost::thread::id转化为DWORD类型成了困扰我的一大问题。

而且,通过多次试验发现,GetCurrentThreadId()方法有时返回的是16进制的线程ID,有时是10进制。下面的两个运行结果为证:第一个截图,发现GetCurrentThreadId()方法有时返回的是10进制的线程ID,与自己通过某些方法转换出来的一致;第二个截图发现GetCurrentThreadId()方法有时返回的是16进制的线程ID。
在这里插入图片描述
在这里插入图片描述
程序如下:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <Windows.h>
#include <boost/lexical_cast.hpp>
using namespace boost;

void thread2(int x){
	std::cout << "thrd2 的线程ID(windows):" << GetCurrentThreadId() << std::endl;
	//Sleep(1000);
}

DWORD getThreadId(boost::thread::id id){
	std::string threadId = boost::lexical_cast<std::string>(id);
	DWORD threadNumber = 0;
	threadNumber = std::stoul(threadId, nullptr, 16);
	//sscanf(threadId.c_str(), "%lx", &threadNumber); //也可以使用这个句子完成转换
	return threadNumber;
}

int main(){
	boost::thread thrd2(boost::bind(&thread2, 2));
	std::cout << "thrd2 的线程ID:" << thrd2.get_id() << std::endl;
	//通过getThreadId方法获取线程DWORD形式的ID
	DWORD id = getThreadId(thrd2.get_id());
	std::cout << "thrd2 的线程ID(通过getThreadId方法获得):" << getThreadId(thrd2.get_id())<< std::endl;
	if (thrd2.joinable()){
		thrd2.join();
		std::cout << "thrd2 的线程ID:" << thrd2.get_id() << std::endl;
	}
	if (!thrd2.joinable()){
		std::cout << "thrd2 is unjoinable" << std::endl;
	}

	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	return 0;
}

就觉得超级神奇,怎么GetCurrentThreadId()方法有时返回的是16进制的线程ID,有时是10进制?后来将程序中的//Sleep(1000);解除注释,发现GetCurrentThreadId()方法输出10进制的概率更高了,但是有时还是会输出16进制。

实现线程ID转换,参考链接:
How to retrieve the thread id from a boost::thread?
boost获取threadid


新的想法:如果转换得到的线程ID能与`GetCurrentThreadId()`方法得到的线程ID比较大小,说明应该就可以使用使用`PostMessage()`和`PeekMessage()`进行线程间通信。**虽然一个是16进制,一个是10进制,竟然是一样大的。。。**
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <Windows.h>
#include <boost/lexical_cast.hpp>
using namespace boost;
DWORD getThreadId(boost::thread::id id){
	std::string threadId = boost::lexical_cast<std::string>(id);
	DWORD threadNumber = 0;
	//threadNumber = std::stoul(threadId, nullptr, 16);
	sscanf(threadId.c_str(), "%lx", &threadNumber);
	return threadNumber;
}
void thread2(int x){
	DWORD id1 = GetCurrentThreadId();
	std::cout << "thrd2 的线程ID(windows):" << GetCurrentThreadId() << std::endl;

	//通过getThreadId方法获取线程DWORD形式的ID
	DWORD id2 = getThreadId(boost::this_thread::get_id());
	std::cout << "thrd2 的线程ID(通过getThreadId方法获得):" << id2 << std::endl;
	if (id1 = id2){
		std::cout << "两种方式获取的线程ID一样大"<< std::endl;
	}
	else{
		std::cout << "两种方式获取的线程ID不一样大" << std::endl;
	}
}

int main(){
	boost::thread thrd2(boost::bind(&thread2, 2));
	std::cout << "thrd2 的线程ID:" << thrd2.get_id() << std::endl;
	thrd2.join();
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;
	std::cout << "this is main()" << std::endl;

	return 0;
}

程序运行截图:
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐