C/C++ 原生API实现线程池的方法

线程池有两个核心的概念,一个是任务队列,一个是工作线程队列。任务队列负责存放主线程需要处理的任务,工作线程队列其实是一个死循环,负责从任务队列中取出和运行任务,可以看成是一个生产者和多个消费l者的模型。在一些高并发的网络应用中,线程池也是常用的技术。陈硕大神推荐的C++多线程服务端编程模式为:one loop per thread + thread pool,通常会有单独的线程负责接受来自客户端的请求,对请求稍作解析后将数据处理的任务提交到专门的计算线程池。

ThreadPool 线程池同步事件: 线程池内的线程函数同样支持互斥锁,信号控制,内核事件控制,临界区控制.

#include <Windows.h>
#include <iostream>
#include <stdlib.h>

unsigned long g_count = 0;

// --------------------------------------------------------------
// 线程池同步-互斥量同步
void NTAPI TaskHandlerMutex(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	// 锁定资源
	WaitForSingleObject(*(HANDLE *)Context, INFINITE);

	for (int x = 0; x < 100; x++)
	{
		printf("线程ID: %d ---> 子线程: %d \n", GetCurrentThreadId(), x);
		g_count = g_count + 1;
	}

	// 解锁资源
	ReleaseMutexWhenCallbackReturns(Instance, *(HANDLE*)Context);
}

void TestMutex()
{
	// 创建互斥量
	HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);

	PTP_WORK pool = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerMutex, &hMutex, NULL);

	for (int i = 0; i < 1000; i++)
	{
		SubmitThreadpoolWork(pool);
	}

	WaitForThreadpoolWorkCallbacks(pool, FALSE);
	CloseThreadpoolWork(pool);
	CloseHandle(hMutex);

	printf("相加后 ---> %d \n", g_count);
}

// --------------------------------------------------------------
// 线程池同步-事件内核对象
void NTAPI TaskHandlerKern(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	// 锁定资源
	WaitForSingleObject(*(HANDLE *)Context, INFINITE);

	for (int x = 0; x < 100; x++)
	{
		printf("线程ID: %d ---> 子线程: %d \n", GetCurrentThreadId(), x);
		g_count = g_count + 1;
	}

	// 解锁资源
	SetEventWhenCallbackReturns(Instance, *(HANDLE*)Context);
}

void TestKern()
{
	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	SetEvent(hEvent);

	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerKern, &hEvent, NULL);

	for (int i = 0; i < 1000; i++)
	{
		SubmitThreadpoolWork(pwk);
	}

	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	CloseThreadpoolWork(pwk);

	printf("相加后 ---> %d \n", g_count);
}

// --------------------------------------------------------------
// 线程池同步-信号量同步
void NTAPI TaskHandlerSemaphore(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	// 锁定资源
	WaitForSingleObject(*(HANDLE *)Context, INFINITE);

	for (int x = 0; x < 100; x++)
	{
		printf("线程ID: %d ---> 子线程: %d \n", GetCurrentThreadId(), x);
		g_count = g_count + 1;
	}

	// 解锁资源
	ReleaseSemaphoreWhenCallbackReturns(Instance, *(HANDLE*)Context, 1);
}

void TestSemaphore()
{
	// 创建信号量为100
	HANDLE hSemaphore = CreateSemaphore(NULL, 0, 100, NULL);

	ReleaseSemaphore(hSemaphore, 10, NULL);

	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerSemaphore, &hSemaphore, NULL);

	for (int i = 0; i < 1000; i++)
	{
		SubmitThreadpoolWork(pwk);
	}

	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	CloseThreadpoolWork(pwk);
	CloseHandle(hSemaphore);

	printf("相加后 ---> %d \n", g_count);
}

// --------------------------------------------------------------
// 线程池同步-临界区
void NTAPI TaskHandlerLeave(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	// 锁定资源
	EnterCriticalSection((CRITICAL_SECTION*)Context);

	for (int x = 0; x < 100; x++)
	{
		printf("线程ID: %d ---> 子线程: %d \n", GetCurrentThreadId(), x);
		g_count = g_count + 1;
	}

	// 解锁资源
	LeaveCriticalSectionWhenCallbackReturns(Instance, (CRITICAL_SECTION*)Context);
}

void TestLeave()
{
	CRITICAL_SECTION cs;
	InitializeCriticalSection(&cs);

	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerLeave, &cs, NULL);

	for (int i = 0; i < 1000; i++)
	{
		SubmitThreadpoolWork(pwk);
	}

	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	DeleteCriticalSection(&cs);
	CloseThreadpoolWork(pwk);

	printf("相加后 ---> %d \n", g_count);
}

int main(int argc,char *argv)
{
	//TestMutex();
	//TestKern();
	//TestSemaphore();
	TestLeave();

	system("pause");
	return 0;
}

简单的IO读写:

#include <Windows.h>
#include <iostream>
#include <stdlib.h>

// 简单的异步文本读写
int ReadWriteIO()
{
	char enContent[] = "hello lyshark";
	char deContent[255] = { 0 };

	// 异步写文件
	HANDLE hFileWrite = CreateFile(L"d://test.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if (INVALID_HANDLE_VALUE == hFileWrite)
	{
		return 0;
	}

	WriteFile(hFileWrite, enContent, strlen(enContent), NULL, NULL);
	FlushFileBuffers(hFileWrite);

	CancelSynchronousIo(hFileWrite);
	CloseHandle(hFileWrite);

	// 异步读文件

	HANDLE hFileRead = CreateFile(L"d://test.txt", GENERIC_READ, 0, NULL, OPEN_ALWAYS, NULL, NULL);
	if (INVALID_HANDLE_VALUE == hFileRead)
	{
		return 0;
	}

	ReadFile(hFileRead, deContent, 255, NULL, NULL);
	CloseHandle(hFileRead);
	std::cout << "读出内容: " << deContent << std::endl;
	return 1;
}

// 通过IO获取文件大小
int GetFileSize()
{
	HANDLE hFile = CreateFile(L"d://test.txt", 0, 0, NULL, OPEN_EXISTING, NULL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return 0;
	}

	ULARGE_INTEGER ulFileSize;
	ulFileSize.LowPart = GetFileSize(hFile, &ulFileSize.HighPart);

	LARGE_INTEGER lFileSize;
	BOOL ret = GetFileSizeEx(hFile, &lFileSize);

	std::cout << "文件大小A: " << ulFileSize.QuadPart << " bytes" << std::endl;
	std::cout << "文件大小B: " << lFileSize.QuadPart << " bytes" << std::endl;
	CloseHandle(hFile);

	return 1;
}

// 通过IO设置文件指针和文件尾
int SetFilePointer()
{
	char deContent[255] = { 0 };
	DWORD readCount = 0;

	HANDLE hFile = CreateFile(L"d://test.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, NULL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return 0;
	}

	LARGE_INTEGER liMove;

	// 设置移动位置
	liMove.QuadPart = 2;
	SetFilePointerEx(hFile, liMove, NULL, FILE_BEGIN);

	// 移动到文件末尾
	SetEndOfFile(hFile);

	ReadFile(hFile, deContent, 255, &readCount, NULL);
	std::cout << "移动指针后读取: " << deContent << " 读入长度: " << readCount << std::endl;

	CloseHandle(hFile);

	// 设置编码格式
	_wsetlocale(LC_ALL, L"chs");
	setlocale(LC_ALL, "chs");
	wprintf(L"%s", deContent);
}

int main(int argc,char *argv)
{
	// 读写IO
	ReadWriteIO();

	// 取文件长度
	GetFileSize();

	// 设置文件指针
	SetFilePointer();

	return 0;
}

到此这篇关于C/C++ 原生API实现线程池的文章就介绍到这了,更多相关C++实现线程池内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于C++11的threadpool线程池(简洁且可以带任意多的参数)

    C++11 加入了线程库,从此告别了标准库不支持并发的历史.然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池.信号量等.线程池(thread pool)这个东西,在面试上多次被问到,一般的回答都是:"管理一个任务队列,一个线程队列,然后每次取一个任务分配给一个线程去做,循环往复." 貌似没有问题吧.但是写起程序来的时候就出问题了. 废话不多说,先上实现,然后再啰嗦.(dont talk, show me ur code !) 代码实现 #pra

  • 深入解析C++编程中线程池的使用

    为什么需要线程池 目前的大多数网络服务器,包括Web服务器.Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短. 传 统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行任务.任务执行完毕后,线程退出,这就是是"即时创建,即 时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器将处于 不停的创建线程,

  • C++线程池的简单实现方法

    本文以实例形式较为详细的讲述了C++线程池的简单实现方法.分享给大家供大家参考之用.具体方法如下: 一.几个基本的线程函数: 1.线程操纵函数: int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void *), void *arg); //创建 void pthread_exit(void *retval); //终止自身 int pthread_cancel(pthread_

  • c++版线程池和任务池示例

    commondef.h 复制代码 代码如下: //单位秒,监测空闲列表时间间隔,在空闲队列中超过TASK_DESTROY_INTERVAL时间的任务将被自动销毁const int CHECK_IDLE_TASK_INTERVAL = 300;//单位秒,任务自动销毁时间间隔const int TASK_DESTROY_INTERVAL = 60; //监控线程池是否为空时间间隔,微秒const int IDLE_CHECK_POLL_EMPTY = 500; //线程池线程空闲自动退出时间间隔

  • c++实现简单的线程池

    这是对pthread线程的一个简单应用 1.      实现了线程池的概念,线程可以重复使用. 2.      对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码. 3.      移植性好.如果想把这个线程池代码应用到自己的实现中去,只要写自己的业务处理函数和改写工作队列数据的处理方法就可以了. Sample代码主要包括一个主程序和两个线程实现类 ThreadTest.cpp:主程序 CThreadManager:线程管理Class,线程池的实现类 CThread:线程Class

  • C/C++ 原生API实现线程池的方法

    线程池有两个核心的概念,一个是任务队列,一个是工作线程队列.任务队列负责存放主线程需要处理的任务,工作线程队列其实是一个死循环,负责从任务队列中取出和运行任务,可以看成是一个生产者和多个消费l者的模型.在一些高并发的网络应用中,线程池也是常用的技术.陈硕大神推荐的C++多线程服务端编程模式为:one loop per thread + thread pool,通常会有单独的线程负责接受来自客户端的请求,对请求稍作解析后将数据处理的任务提交到专门的计算线程池. ThreadPool 线程池同步事件

  • python实现线程池的方法

    本文实例讲述了python实现线程池的方法.分享给大家供大家参考.具体如下: 原理:建立一个任务队列,然多个线程都从这个任务队列中取出任务然后执行,当然任务队列要加锁,详细请看代码 文件名:thrd_pool.py 系统环境:ubuntu linux & python2.6 import threading import time import signal import os class task_info(object): def __init__(self): self.func = No

  • c++线程池实现方法

    本文实例讲述了c++线程池实现方法.分享给大家供大家参考.具体分析如下: 下面这个线程池是我在工作中用到过的,原理还是建立一个任务队列,让多个线程互斥的在队列中取出任务,然后执行,显然,队列是要加锁的 环境:ubuntu linux 文件名:locker.h #ifndef LOCKER_H_ #define LOCKER_H_ #include "pthread.h" class locker { public: locker(); virtual ~locker(); bool l

  • Python自定义线程池实现方法分析

    本文实例讲述了Python自定义线程池实现方法.分享给大家供大家参考,具体如下: 关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主要思路: 任务获取和执行: 1.任务加入队列,等待线程来获取并执行. 2.按需生成线程,每个线程循环取任务. 线程销毁: 1.获取任务是终止符时,线程停止. 2.线程池close()时,向任务队列加入和已生成线程等量的

  • 一种类似JAVA线程池的C++线程池实现方法

    什么是线程池 线程池(thread pool)是一种线程使用模式.线程过多或者频繁创建和销毁线程会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着管理器分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的代价,以及保证了线程的可复用性.线程池不仅能够保证内核的充分利用,还能防止过分调度. 线程池的实现 线程池在JAVA平台上已经有成熟的实现方式,本文介绍参考JAVA线程池实现方式实现的C++线程池类库. 该类库代码已上传至github仓库中,下载地址为:ht

  • C++11 简单实现线程池的方法

    什么是线程池 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程完成后才启动. 不使用

  • 火遍全网的Hutool使用Builder模式创建线程池的方法

    前言 Builder 设计模式也叫做 构建者模式或者建造者模式,名字只是一种叫法,当聊起三种名称的时候知道是怎么回事就行 Builder 设计模式在作者编码过程中,属于比较常用的模式之一.优秀的设计模式总是会受到广大开发者的青睐,Hutool 也是其中之一 因为上周编写的业务需要用到线程池,就去 Hutool thread 包下看了看,还真有惊喜,学习到了一种之前编码中没用过的 Builder 模式实现 这里必须提一句:设计模式重要的是思想,一种设计模式可能不止一种实现方式 Builder 模式

  • Node.js原生api搭建web服务器的方法步骤

    node.js 实现一个简单的 web 服务器还是比较简单的,以前利用 express 框架实现过『nodeJS搭一个简单的(代理)web服务器』.代码量很少,可是使用时需要安装依赖,多处使用难免有点不方便.于是便有了完全使用原生 api 来重写的想法,也当作一次 node.js 复习. 1.静态 web 服务器 'use strict' const http = require('http') const url = require('url') const fs = require('fs'

  • java 注解实现一个可配置线程池的方法示例

    前言 项目需要多线程执行一些Task,为了方便各个服务的使用.特意封装了一个公共工具类,下面直接撸代码: PoolConfig(线程池核心配置参数): /** * <h1>线程池核心配置(<b style="color:#CD0000">基本线程池数量.最大线程池数量.队列初始容量.线程连接保持活动秒数(默认60s)</b>)</h1> * * <blockquote><code> * <table bord

  • Java线程池execute()方法源码全面解析

    先看作者给出的注释来理解线程池到底有什么作用 * Thread pools address two different problems: they usually * provide improved performance when executing large numbers of * asynchronous tasks, due to reduced per-task invocation overhead, * and they provide a means of boundin

随机推荐