[开源世界]简单的线程库

C#的线程有thread、timer、dispatch、task等几种类型,而平时在C++工程中也常常会遇到这几种线程模型,我在思考C#是怎么实现的基础上实作了该线程库,希望能简化开发难度。
#ifndef __Easy_Thread_H__
#define __Easy_Thread_H__


#include <stdlib.h>


// 线程对象
typedef uintptr_t easy_thread;

// 任务对象
typedef uintptr_t easy_task;


// 线程入口
typedef int (*easy_thread_startup)(void* param);

// 线程结束
typedef void (*easy_thread_close)(int exitcode, void* param);


// 界面更新
typedef int (*easy_thread_dispatch)(void* param);


// 任务执行
typedef int (*easy_task_startup)(void* param);

// 任务结束
typedef void (*easy_task_close)(int exitcode, void* param);


// easy_thread的消息码
extern const int easy_msg_id;


// 初始化类库
int easy_thread_init();


// 清理类库
int easy_thread_cleanup();



// 新建线程
easy_thread easy_thread_new(easy_thread_startup startup, void* param, easy_thread_close close);


// 等待线程执行完成
void easy_thread_wait(easy_thread thread, int timeout);


// 中断线程执行
void easy_thread_terminate(easy_thread thread);



// 新建界面更新操作
int easy_thread_new_dispatch(void* hWnd, easy_thread_dispatch dispatch, void* param);


// 为Windows的消息处理过程设计的界面线程处理函数
int easy_thread_wnd_proc(void* hWnd, int msg);



// 新建任务
easy_task easy_task_new(easy_task_startup task, void* param, easy_task_close close);

// 取消任务
void easy_task_cancel(easy_task task);



#endif /*__Easy_Thread_H__*/
#include <list>
using namespace std;


#include "easy_thread.h"
#include "simclist.h"
#include <process.h>
#include <Windows.h>


// easy_thread的消息码
const int easy_msg_id = ::RegisterWindowMessageA("easy_msg_id");


// 界面命令列表
static list_t g_easy_thread_dispatch_list;


// 任务命令列表
static list_t g_easy_thread_task_list;

// 任务处理线程
static easy_thread g_easy_thread_task_thread;

// 任务处理事件
static HANDLE g_easy_thread_task_event;

// 任务处理线程退出
static bool g_easy_thread_task_exit;

// 前置声明
static int easy_thread_task_proc(void* param);


// 初始化类库
int easy_thread_init()
{
	list_init(&g_easy_thread_dispatch_list);
	
	list_init(&g_easy_thread_task_list);

	g_easy_thread_task_exit = false;

	g_easy_thread_task_event = CreateEvent(NULL, true, false, NULL);
	ResetEvent(g_easy_thread_task_event);

	g_easy_thread_task_thread = easy_thread_new(easy_thread_task_proc, NULL, NULL);

	return 0;
}


// 清理类库
int easy_thread_cleanup()
{
	if (list_iterator_start(&g_easy_thread_dispatch_list) > 0)
	{
		while (list_iterator_hasnext(&g_easy_thread_dispatch_list) > 0)
		{
			delete list_iterator_next(&g_easy_thread_dispatch_list);
		}
		list_iterator_stop(&g_easy_thread_dispatch_list);
	}

	list_destroy(&g_easy_thread_dispatch_list);

	//

	g_easy_thread_task_exit = true;
	WaitForSingleObject((HANDLE)g_easy_thread_task_thread, INFINITE);

	if (list_iterator_start(&g_easy_thread_task_list) > 0)
	{
		while (list_iterator_hasnext(&g_easy_thread_task_list) > 0)
		{
			delete list_iterator_next(&g_easy_thread_task_list);
		}
		list_iterator_stop(&g_easy_thread_task_list);
	}

	list_destroy(&g_easy_thread_task_list);

	return 0;
}


/*
 * easy_thread_dispatch_node
 */

class easy_thread_dispatch_node
{
public:
	easy_thread_dispatch_node(void* hwnd, easy_thread_dispatch dispatch, void* param)
	{
		this->hwnd = hwnd;
		this->param = param;
		this->dispatch = dispatch;		
	}
public:
	void* hwnd;
	void* param;
	easy_thread_dispatch dispatch;	
};


// 为Windows的消息处理过程设计的界面线程处理函数
int easy_thread_wnd_proc(void* hWnd, int msg)
{
	if (easy_msg_id != msg)
	{
		return 0;
	}

	if (list_iterator_start(&g_easy_thread_dispatch_list) > 0)
	{
		int iIter = 0;

		list<int> delete_list;

		easy_thread_dispatch_node* node = NULL;

		while (list_iterator_hasnext(&g_easy_thread_dispatch_list) > 0)
		{
			node = (easy_thread_dispatch_node*)list_iterator_next(&g_easy_thread_dispatch_list);

			// 在当前窗口的消息循环内
			if (hWnd == node->hwnd)
			{
				// 执行界面更新命令
				if (node->dispatch != NULL)
				{					
					node->dispatch(node->param);
				}				

				// 删除节点
				delete node;

				// 标记当前节点,需要删除
				delete_list.push_back(iIter);
			}

			iIter++;
		}

		list_iterator_stop(&g_easy_thread_dispatch_list);

		for (auto iter = delete_list.rbegin(); iter != delete_list.rend(); ++iter)
		{
			list_delete_at(&g_easy_thread_dispatch_list, *iter);
		}
	}

	return 0;
}


/*
 * easy_start_address_param
 */

struct easy_start_address_param
{
	easy_thread_startup startup;
	void* param;
	easy_thread_close close;
	bool cancel;

	easy_start_address_param(easy_thread_startup startup, void* param, easy_thread_close close)
	{
		this->startup = startup;
		this->param = param;
		this->close = close;
		cancel = false;
	}
};


// 线程启动的入口函数
static void __cdecl easy_thread_start_address(void* param)
{
	struct easy_start_address_param* addr_param = (struct easy_start_address_param *)param;
	
	if (addr_param != NULL && addr_param->startup != NULL)
	{
		// 执行线程命令
		int exit_code = addr_param->startup(addr_param->param);
		
		if (addr_param->close != NULL)
		{
			// 通知线程即将退出
			addr_param->close(exit_code, addr_param->param);
		}

		// 删除函数参数
		delete addr_param;
	}
}


// 新建线程处理函数
easy_thread easy_thread_new(easy_thread_startup startup, void* param, easy_thread_close close)
{
	uintptr_t thread = _beginthread(easy_thread_start_address, 0, new easy_start_address_param(startup, param, close));
	return thread;
}


// 等待线程执行完成
void easy_thread_wait(easy_thread thread, int timeout)
{
	WaitForSingleObject((HANDLE)thread, (timeout == -1) ? INFINITE : timeout);
}


// 中断线程执行
void easy_thread_terminate(easy_thread thread)
{
}


// 新建界面更新操作
int easy_thread_new_dispatch(void* hWnd, easy_thread_dispatch dispatch, void* param)
{
	// 将界面更新命令添加到命令队列中
	list_append(&g_easy_thread_dispatch_list, new easy_thread_dispatch_node(hWnd, dispatch, param));

	// 向需要更新界面的窗口发送界面更新消息
	SendMessage((HWND)hWnd, easy_msg_id, 0, 0);

	return 0;
}


// 任务处理入口函数
static int easy_thread_task_proc(void* param)
{
	while (!g_easy_thread_task_exit)
	{
		if (list_size(&g_easy_thread_task_list) == 0)
		{
			ResetEvent(g_easy_thread_task_event);
			WaitForSingleObject(g_easy_thread_task_event, 300);
		}
		else
		{
			easy_start_address_param* node = (easy_start_address_param*)list_get_at(&g_easy_thread_task_list, 0);

			if (!node->cancel && node->startup != NULL)
			{
				int exitcode = node->startup(node->param);

				if (node->close != NULL)
				{
					node->close(exitcode, node->param);
				}				
			}

			// 删除节点
			delete node;

			list_delete_at(&g_easy_thread_task_list, 0);
		}
	}

	return 0;
}


// 新建任务
easy_task easy_task_new(easy_task_startup task, void* param, easy_task_close close)
{
	easy_start_address_param* task_addr = new easy_start_address_param(task, param, close);

	// 将任务命令添加到命令队列中
	list_append(&g_easy_thread_task_list, task_addr);

	SetEvent(g_easy_thread_task_event);

	return (easy_task)task_addr;
}


// 取消任务
void easy_task_cancel(easy_task task)
{
	easy_start_address_param* task_addr = (easy_start_address_param *)task;
	task_addr->cancel = true;
}

转载于:https://my.oschina.net/lvan100/blog/169816

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值