📄 dataanalyzer.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 + -