使用全局变量进行通信
对于标准型的全局变量,建议使用volatile修饰符,告诉编译器无需优化(不放入寄存器),该值可以被外部改变。
如果线程间需要传递的信息比较复杂,可以使用结构,通过传递指向结构的指针来传递信息。
volatile修饰符
-
防止编译器优化
声明为volatile的变量不会被编译器优化,每次访问都会直接读取内存值,避免因优化导致的数据不一致问题。 12
-
保证内存可见性
在多线程环境中,volatile变量的修改会立即同步到主内存,其他线程能读取到最新值,解决线程间数据不一致问题。 34
-
禁止指令重排序
通过插入内存屏障,防止编译器或处理器对volatile变量相关指令进行重排序,确保程序执行顺序符合预期。
如链接示例中
cpp
volatile bool bExit1 = false;
volatile bool bExit2 = false;
...
void CMFCApplDlg::OnPriorityThread1()
{
int prior;
//线程存在
if (m_pThread1 && !bExit1)
{
prior = m_pThread1->GetThreadPriority();
if (prior == THREAD_PRIORITY_NORMAL )
{
m_pThread1->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
AfxMessageBox(L"线程1的优先级提升1级", MB_OK);
}
else
{
m_pThread1->SetThreadPriority(THREAD_PRIORITY_NORMAL);
AfxMessageBox(L"线程1的优先级降低1级", MB_OK);
}
}
}
void CMFCApplDlg::OnPriorityThread2()
{
int prior;
//线程存在
if (m_pThread2 && !bExit2)
{
prior = m_pThread2->GetThreadPriority();
if (prior == THREAD_PRIORITY_NORMAL)
{
m_pThread2->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
AfxMessageBox(L"线程2的优先级提升1级", MB_OK);
}
else
{
m_pThread2->SetThreadPriority(THREAD_PRIORITY_NORMAL);
AfxMessageBox(L"线程2的优先级降低1级", MB_OK);
}
}
}
....
void CMFCApplDlg::OnStopThread1()
{
bExit1 = true;
m_bEnable1 = true;
}
void CMFCApplDlg::OnStopThread2()
{
bExit2 = true;
m_bEnable2 = true;
}
使用自定义消息进行通信
步骤
1)定义一个自定义消息。
在头文件中自定义消息、声明消息处理函数。
在CPP文件中,映射消息,定义消息处理函数。
2)在一个函数中调用::PostMessage()向另一个线程发送自定义消息
PostMessageA 函数
cpp
BOOL PostMessageA(
[in, optional] HWND hWnd,
[in] UINT Msg,
[in] WPARAM wParam,
[in] LPARAM lParam
);
hWnd:窗口过程的句柄是接收消息。 以下值具有特殊含义。
| 价值 | 意义 |
|---|---|
| HWND_BROADCAST ((HWND)0xffff) | 该消息将发布到系统中的所有顶级窗口,包括已禁用或不可见的未所有者窗口、重叠的窗口和弹出窗口。 消息不会发布到子窗口。 |
| 零 | 该函数的行为类似于调用 PostThreadMessage,dwThreadId 参数设置为当前线程的标识符。 |
Msg:要发布的消息。
wParam:其他特定于消息的信息。
lParam:其他特定于消息的信息。
返回值:如果函数成功,则返回值为非零。如果函数失败,则返回值为零。
范例



cpp
UINT CalcPrime(LPVOID param);


cpp
int n = 0;
UINT CalcPrime(LPVOID param)
{
n = 0;
long j, k;
for (long i = 1; i <= 100000000; i += 2)
{
k = (long)sqrt(i);
for (j = 2; j <= k; j++)
{
if (i % j == 0)
{
break;
}
}
if (j >= k + 1)
{
n += 1;
}
}
return 0;
}




程序优化

cpp
const int WM_CALCULATE = WM_USER + 100;//自定义消息
...
afx_msg LONG OnThreadEnd(WPARAM aParam, LPARAM lParam);//消息处理函数



cpp
BEGIN_MESSAGE_MAP(CMFCDlg, CDialogEx)
...
ON_MESSAGE(WM_CALCULATE, OnThreadEnd)//自定义消息映射
END_MESSAGE_MAP()
LONG CMFCDlg::OnThreadEnd(WPARAM aParam, LPARAM lParam)
{
CString s;
s.Format(L"当前个数:%d .", n);
AfxMessageBox(s);
return 0;
}
void CMFCDlg::OnBnClickedPrime()
{
HWND hWnd = GetSafeHwnd();//获取窗口句柄
AfxBeginThread(CalcPrime, hWnd);
}
UINT CalcPrime(LPVOID param)
{
n = 0;
long j, k;
for (long i = 1; i <= 10000000; i += 2)
{
k = (long)sqrt(i);
for (j = 2; j <= k; j++)
{
if (i % j == 0)
{
break;
}
}
if (j >= k + 1)
{
n += 1;
}
}
::PostMessage((HWND)param, WM_CALCULATE, n, 0);//向主线程发送消息WM_CALCULATE
return 0;
}
当计算结束,自动弹出对话框。这才是想要的结果
