Boost编程之--使用thread类提高线程开发效率

用Windows API写线程,最痛苦的莫过于:

1. 记不住CreateThread长长的参数,对于普通人,参数超过3个,就变得很难记住了。

2. 线程参数表只有一个LPVOID,多参数情况下,我需要将其封装在类或者结构体里。

3. 变量的同步与异常处理。


比如我想创建两个线程,第一个线程输出: Thread1 : 1 ~ Thread1: 5;第二个线程接着输出:Thread2 : 6 ~ Thread2 : 10。两个线程共用一个int变量,从1递增到10。输出如下图:

Boost编程之--使用thread类提高线程开发效率_第1张图片

以下是我用WIN32 API写的代码,是不是觉得比较麻烦?对于多参数,我痛恨每次都要写个struct指针来将其传递给线程,为什么线程不能是多参数的?Windows窗口消息起码还包括了WPARAM和LPARAM两个参数。

#include 
#include 
#include 

using namespace std;

struct MyStruct
{
	string str;
	volatile int* nIndex;
};

CRITICAL_SECTION CK;

DWORD WINAPI Win32_Thread(LPVOID pStruct)
{
	EnterCriticalSection(&CK);
	MyStruct* myStruct = (MyStruct*)(pStruct);
	for (int i = 0; i < 5; ++i)
	{
		cout << myStruct->str << ": " << ++(*myStruct->nIndex) << endl;
	}
	LeaveCriticalSection(&CK);
	return 0;
}

int main()
{
	// 创建临界区。
	::InitializeCriticalSection(&CK);

	// 创建第一个线程,输出Thread1。
	MyStruct myStruct;
	myStruct.nIndex		= new int;
	*myStruct.nIndex	= 0;
	myStruct.str		= "Thread1";

	DWORD dwID1, dwID2;
	::CreateThread(NULL, 0, &Win32_Thread, &myStruct, 0, &dwID1);

	// 创建第二个线程,输出Thread2。
	MyStruct myStruct2;
	myStruct2.nIndex	= myStruct.nIndex;
	myStruct2.str		= "Thread2";
	::CreateThread(NULL, 0, &Win32_Thread, &myStruct2, 0, &dwID2);

	// 等待两个线程结束。
	::Sleep(3000);

	// 销毁临界区及新建的指针。
	DeleteCriticalSection(&CK);
	delete myStruct.nIndex;
	myStruct.nIndex = NULL;

	getchar();
	return 0;
}

接下来,让我们看看用Boost库编写,会将代码简化到何种程度:

#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace boost;

mutex io_mutex;

// 线程print,不再需要DWORD WINAPI这个声明了。
// 当然LPVOID也消失了,thread类最多支持9个参数。
void print(atomic_int& nIndex, const string& str)
{
	mutex::scoped_lock lock(io_mutex);
	for (int i = 0; i < 5; ++i)
	{
		cout << str << ": " << ++(nIndex) << endl;
	}
}

int main()
{
	// 原子操作。
	atomic_int nIndex = 0;

	// 创建两个线程,传入两个参数,一个是nIndex的引用,另一个是字符串。
	thread(print, boost::ref(nIndex), "Hello");
	thread(print, boost::ref(nIndex), "Boost");

	getchar();
	return 0;
}
输出结果如下:

Boost编程之--使用thread类提高线程开发效率_第2张图片
短短几行代码,就完成了该功能,是不是很有效率?不仅如此,我还发现了其他优点:

1. 临界区的编写不再有初始化和释放等操作,这将有利于异常处理。

2. 从头到尾没有见到指针的声明与操作,指针传递被boost::ref()替代了。

3. 支持多参数传递,最大传递的参数个数为9个;

4. 只要是个函数,都可以将其用作线程,而不再需要格式化的声明为:DWORD WINAPI fun(LPVOID lpPram);

小结:在日常工作中,如果涉及到线程的开发,不妨先考虑下Boost库。

你可能感兴趣的:(C++,Boost)