中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C/C++ 原生API實現線程池的方法是什么

發布時間:2021-11-02 17:38:57 來源:億速云 閱讀:128 作者:iii 欄目:開發技術

本篇內容主要講解“C/C++ 原生API實現線程池的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“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實現線程池的方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

崇明县| 灌南县| 乌恰县| 长子县| 哈巴河县| 普兰店市| 平乡县| 元谋县| 微山县| 酉阳| 平舆县| 康平县| 娱乐| 陵川县| 双城市| 三原县| 府谷县| 扶风县| 荃湾区| 牡丹江市| 望江县| 开封市| 上杭县| 宝丰县| 焦作市| 洛宁县| 通河县| 遵义县| 开封县| 芷江| 内江市| 渑池县| 房山区| 钦州市| 保德县| 贺兰县| 茌平县| 镇原县| 浦城县| 福清市| 金昌市|