<类中开启一个线程, 并和主线程用消息通讯>的代码, 为什么总报错..

HoNooD 2009-11-08 11:51:26
想实现的功能是, 创建一个类(单例类, 这里简化了), 这个类创建的时候就开启一个新线程并立即执行. 该线程的任务是获取最新的数据, 并以消息形式通知主线程, 然后主线程更新类的成员变量.

我写的代码:

#include <iostream>
#include <stdio.h>
#include <windows.h>

using namespace std;

struct ExDataType
{
int id;
double value;
};

#define UM_DATA_ACQUIRE (WM_USER + 1001)

class A
{
public:
A();
void Update();
void Show();
private:
DWORD WINAPI ThreadFunc(LPVOID para);
ExDataType m_data;
};

A::A()
{
m_data.id = 0;
m_data.value = 0.0;

DWORD dwValue = GetCurrentThreadId();
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, &dwValue, 0, NULL);
if (!hThread)
{
std::cout << "error\r\n";
exit(-1);
}
//CloseHandle(hThread);
}

void A::Update()
{
MSG msg;
ExDataType *pTmp = NULL;
while(GetMessage(&msg, NULL, 0, 0))
{
pTmp = (ExDataType *)(msg.wParam);
switch(msg.message)
{
case UM_DATA_ACQUIRE:
m_data.id = pTmp->id;
m_data.value = pTmp->value;
break;
default:
break;
}
}
}

void A::Show()
{
std::cout << "m_data.id: " << m_data.id << "\tm_data.value: " << m_data.value << "\r\n";
}

DWORD WINAPI A::ThreadFunc(LPVOID para)
{
DWORD dwThreadId = *((DWORD *)para);
ExDataType threadData = {0, 0.0};

while(TRUE)
{
threadData.id += 2;
threadData.value += 2.2;
PostThreadMessage(dwThreadId, UM_DATA_ACQUIRE, (WPARAM)(&threadData), (LPARAM)0);
Sleep(5000);
}

return 0;
}

int main()
{
A a;
a.Show();

return 0;
}


不明白创建线程那里的线程处理函数该怎么写, 另外, 这样能否正确实现我的目的? 请各位高手指教. 非常感谢!
...全文
110 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
HoNooD 2009-11-09
  • 打赏
  • 举报
回复
修改后的代码在这里:

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <ctime>

using namespace std;

#define UM_DATA_ACQUIRE (WM_USER + 1001)

struct ExDataType
{
int id;
double value;
};

DWORD WINAPI ThreadFunc(LPVOID para);

class A
{
public:
A();
void Update();
void Show();
private:
ExDataType m_data;
};

A::A()
{
m_data.id = 1;
m_data.value = 1.1;

DWORD dwValue = GetCurrentThreadId();
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, &dwValue, 0, NULL);
if (!hThread)
{
std::cout << "error\r\n";
exit(-1);
}
CloseHandle(hThread);
}

void A::Update()
{
MSG msg;
ExDataType *pTmp = NULL;
while(GetMessage(&msg, NULL, 0, 0))
{
pTmp = (ExDataType *)(msg.wParam);
switch(msg.message)
{
case UM_DATA_ACQUIRE:
m_data.id = pTmp->id;
m_data.value = pTmp->value;
break;
default:
break;
}
}
}

void A::Show()
{
std::cout << "m_data.id: " << m_data.id << "\tm_data.value: " << m_data.value << "\r\n";
}

DWORD WINAPI ThreadFunc(LPVOID para)
{
DWORD dwThreadId = *(DWORD *)para;
ExDataType threadData = {0, 0.0};
BOOL ret;

while(TRUE)
{
threadData.id += 2;
threadData.value += 2.2;
ret = PostThreadMessage(dwThreadId, UM_DATA_ACQUIRE, (WPARAM)(&threadData), (LPARAM)0);
Sleep(1000);
}

return 0;
}

int main()
{
A a;
int count = 0;
while (5 > count++)
{
a.Show();
Sleep(1000);
}

return 0;
}
HoNooD 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wocow3 的回复:]
ThreadFunc先改成静态成员函数再说。。
[/Quote]
代码改了, 可是要更新的数据总无法更新.
跟了下, 从线程发送信息总失败, 好像是它获得的主线程ID有误, 但不明白这么写哪里错了...
wocow3 2009-11-09
  • 打赏
  • 举报
回复
ThreadFunc先改成静态成员函数再说。。
HoNooD 2009-11-09
  • 打赏
  • 举报
回复
问题查出来了: 虽然传进来的参数是需要更新数据的指针, 但线程函数里面定义了一个局部变量, 更新的只是局部变量.

哎, 太粗心了. 写C语言的函数时这样的错误很少, 到C++里就晕菜了.

感谢楼上回贴的各位朋友!
HoNooD 2009-11-09
  • 打赏
  • 举报
回复
修改了, 可数据还是更新不了...

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

#define UM_DATA_GET (WM_USER + 1001)

struct ExDataType
{
int id;
double value;
};

DWORD WINAPI Thread_Update(LPVOID para);
DWORD WINAPI Thread_GetData(LPVOID para);

CRITICAL_SECTION g_cs;

class A
{
public:
A();
void Show();
private:
DWORD m_threadID;
ExDataType m_data;
};

A::A() : m_threadID(0)
{
m_data.id = 1;
m_data.value = 1.1;

HANDLE hThread_Update = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_Update, (LPVOID)(&m_data), 0, &m_threadID);
if (!hThread_Update)
{
std::cout << "error 1\r\n";
exit(-1);
}
CloseHandle(hThread_Update);

HANDLE hThread_GetData = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_GetData, (LPVOID)(&m_threadID), 0, NULL);
if (!hThread_GetData)
{
std::cout << "error 2\r\n";
exit(-2);
}
CloseHandle(hThread_GetData);
}

void A::Show()
{
EnterCriticalSection(&g_cs);
std::cout << "m_data.id: " << m_data.id << "\tm_data.value: " << m_data.value << "\r\n";
LeaveCriticalSection(&g_cs);
}

DWORD WINAPI Thread_GetData(LPVOID para)
{
DWORD dwThreadId = *(DWORD *)para;
ExDataType threadData = {0, 0.0};
BOOL ret;

while(TRUE)
{
threadData.id += 2;
threadData.value += 2.2;
ret = PostThreadMessage(dwThreadId, UM_DATA_GET, (WPARAM)(&threadData), (LPARAM)0);
Sleep(1000);
}

return 0;
}

DWORD WINAPI Thread_Update(LPVOID para)
{
ExDataType data = *(ExDataType *)para;
MSG msg;
ExDataType *pTmp = NULL;

while(TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) /* GetMessage(&msg, NULL, 0, 0) */
{
EnterCriticalSection(&g_cs);
pTmp = (ExDataType *)(msg.wParam);
switch(msg.message)
{
case UM_DATA_GET:
data.id = pTmp->id;
data.value = pTmp->value;
break;
default:
break;
}
LeaveCriticalSection(&g_cs);
}
}

return 0;
}

int main()
{
InitializeCriticalSection(&g_cs);
A a;
int count = 0;
while (5 > count++)
{
a.Show();
Sleep(1000);
}

DeleteCriticalSection(&g_cs);
return 0;
}
灌水九段 2009-11-09
  • 打赏
  • 举报
回复
Update没调用
a.show白忙活
wocow3 2009-11-09
  • 打赏
  • 举报
回复
1.你这个是console程序,Post消息过来的时候主线程根本没有消息队列,post必然失败。。
A的构造函数调一下PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
2.写了Update为何不调用,那怎么处理消息。。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧