⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataanalyzer.cpp

📁 我用过了
💻 CPP
字号:
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <iostream>
using namespace std;

#include "dataanalyzer.h"


char* DataAnalyzer::datafilepath = NULL;
const int DataAnalyzer::maxthread = 5; // 最大线程数
HANDLE DataAnalyzer::m_hEvent = NULL;


int DataAnalyzer::Run()
{
	MSG msg;

	// 打开事件句柄
	m_hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, "syn_event");

	if(m_hEvent == NULL)
	{
		cout << "没有找到需要的事件。\n"
				<< "DataAnalyzer只能够由DataMaker调用,请勿直接使用.\n";
		cout << "按 ENTER 键退出.....";
		cin.get();
		return -1;
	}

	cout << "DataAnalyzer 正在启动....";
	Sleep(1000);
	cout << "OK\n\n\n";

	// 设置事件为有信号,使得正在等待的 DataMaker 可以继续运行
	SetEvent(m_hEvent);

	while(GetMessage(&msg, NULL, NULL, NULL))
	{
		switch(msg.message)
		{
		case WM_NOTIFY: // DataMaker 数据包写入完毕后收到这个消息
			if(msg.wParam == 1)
			{
				cout << "#### 收到 DataMaker 发送的通知,可以获取数据文件名了.\n";
				HANDLE hfilemap = OpenFileMapping(FILE_MAP_READ, FALSE, "demo_filemapping");
				LPVOID lpview = MapViewOfFile(hfilemap, FILE_MAP_READ, 0, 0, 0);

				cout << "hfilemap = " << hex << hfilemap << ", lpview = " << lpview << endl;
				int nlen = *((int*)lpview);
				datafilepath = new char[nlen];
				memcpy(datafilepath, (BYTE*)lpview + 4, nlen);
				UnmapViewOfFile(lpview);
				CloseHandle(hfilemap);

				cout << "datafilepath : " << datafilepath << endl << endl;
				// 将事件变为有信号,以此通知 DataMaker 已经准备好了。
				SetEvent(m_hEvent);
			}
			else
			{
				cout << "#### 收到 DataMaker 发送的消息,数据已经写入完毕.\n";
				AnalyzingData();
			}
			break;
		case WM_CLOSE: // 任务完成时收到这个消息
			cout << "\n\n\n#### 收到 DataMaker 发送的消息,可以退出运行了.\n";
			delete datafilepath;
			PostQuitMessage(0);
			break;
		}
	}

	// 让事件变为有信号,通知 DataMaker, DataAnalyzer进程即将结束
	SetEvent(m_hEvent);
	CloseHandle(m_hEvent);

	cout << "按 ENTER 键关闭窗口.";
	cin.get();

	return 0;
}

void DataAnalyzer::AnalyzingData()
{
	// 建立管理者线程

	cout << "#### 建立管理者线程.\n";

	DWORD dwThreadID;
	HANDLE hManagerThread = CreateThread(NULL, 0, 
			ManagerThread, 0, CREATE_SUSPENDED, 
			&dwThreadID);

	// 等待管理者线程结束
	cout << "#### 等待管理者线程结束.\n";
	ResumeThread(hManagerThread);
	WaitForSingleObject(hManagerThread, INFINITE);
	CloseHandle(hManagerThread);

	// 让事件变为有信号,通知 DataMaker 分析工作已经结束
	cout << "#### 分析工作已经全部完成.\n\n\n";
	SetEvent(m_hEvent);
}

DWORD DataAnalyzer::ManagerThread(LPVOID lpParameter)
{
	HANDLE* hThreads = new HANDLE[maxthread]; // 保存句柄
	HANDLE* hEvents = new HANDLE[maxthread]; // 保存事件
	threaddata* tds = new threaddata[maxthread]; // 线程需要的数据

	cout << "@@@@ 管理线程开始.\n";

	// 建立事件
	for(int i = 0; i < maxthread; i++)
	{
		hEvents[i] = CreateEvent(NULL, FALSE, TRUE, NULL);
	}

	DWORD dwThreadID;
	SYSTEMTIME stime;
	GetSystemTime(&stime);
	for(int nCount = 0; nCount < stime.wMilliseconds % 10 + 1; nCount++)
	{
		// 等待一个分析线程结束
		i = WaitForMultipleObjects(maxthread, hEvents, FALSE, INFINITE) - WAIT_OBJECT_0;

		// 关闭句柄
		CloseHandle(hThreads[i]);

		// 为分析线程准备数据
		Sleep(350);
		tds[i].hEvent = hEvents[i];
		
		// 模拟读入的数据
		tds[i].number = 0;

		// 建立分析线程但不立刻启动
		hThreads[i] = CreateThread(NULL, 0,
				AnalyzingThread, (LPVOID)&tds[i], 
				0,
				&dwThreadID);
	}

	// 等待所有的分析线程结束
	for(i = 0; i < maxthread; i++)
	{
		WaitForSingleObject(hThreads[i], INFINITE);
		CloseHandle(hEvents[i]);
	}

	delete hThreads;
	delete hEvents;
	delete tds;

	cout << "@@@@ 管理线程结束.\n";
	return 0;
}

DWORD DataAnalyzer::AnalyzingThread(LPVOID lpParameter)
{
	threaddata* ptd = (threaddata*)lpParameter;
	DWORD dwid = GetCurrentThreadId();

	cout << "!!!! " << hex << dwid << " 分析线程开始. START\n";

	// 模拟数据分析过程
	Sleep(ptd->number);

	// 将事件设置为有信号后,前面 ManagerThread 中的
	// i = WaitForMultipleObjects(maxthread, hEvents, FALSE, INFINITE) - WAIT_OBJECT_0
	// 将返回一个已经空闲的句柄的索引
	SetEvent(ptd->hEvent);

	cout << "!!!! " << hex << dwid << " 分析线程结束. END\n";

	return 0;
}


int main(int argc, char* argv[])
{
	DataAnalyzer theObj;
	return theObj.Run();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -