一、线程间通信
Windows线程间通信是Windows编程中一个重要的概念,它允许不同的线程之间交换信息、共享数据和协调它们的工作。以下是Windows线程间通信的几种常见方法:
1. 内存共享
- 原理:由于同一进程内的所有线程都共享相同的地址空间,因此它们可以直接访问进程中的全局变量和静态变量来进行通信。
- 注意事项:
- 使用volatile关键字来定义共享变量,以防止编译器对变量进行优化,确保变量的即时更新。
- 需要考虑线程安全问题,使用互斥锁(mutex)、信号量等同步机制来保证数据的一致性和防止竞争条件。
2 如果在Qt下使用的话
使用信号和槽机制
二、例子
假如我们来实现一下,这样的一个题
1.首先在主线程的窗口上,
有一个按钮.当点击按钮的时候,创建线程。
有三个单选按钮,分别是1+...+10,1+...+100,1+...+1000,当点击任何一个按钮的时候,都要获取要计算的数值
2.在线程函数中,当等到要计算的数值,则开始计算,计算完成,将结果显示到主线程窗口。
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <windows.h>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void on_radioButton_clicked();
void on_radioButton_2_clicked();
void on_radioButton_3_clicked();
signals:
void signalValue(int);
public slots:
void slotValue(int);
private:
Ui::Widget *ui;
public:
HANDLE m_hThread;
bool m_bFlagQuit;
int m_nCalc;
HANDLE m_hEvent;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
m_hThread =0;
m_bFlagQuit = true;
m_nCalc =0;
connect(this,&Widget::signalValue,this,&Widget::slotValue,Qt::QueuedConnection);
//创建事件 自动 无信号
m_hEvent = CreateEvent(0,0,0,0);
}
Widget::~Widget()
{
delete ui;
m_bFlagQuit = false;
if(m_hThread){
if(WAIT_TIMEOUT == WaitForSingleObject(m_hThread,100))
TerminateThread(m_hThread,-1);
CloseHandle(m_hThread);
m_hThread= 0;
}
}
//线程函数
/*
* 事件:内核对象 人工/自动 无信号/有信号
*/
/*
* xx xx xx(xx){
*
* while(1){
* //计算20
* // 发信号
* }
* }
*/
DWORD WINAPI ThreadProc(LPVOID lpvoid){
Widget *pthis = (Widget*)lpvoid;
int nsum = 0;
while(pthis->m_bFlagQuit){
//计算
//等事件有信号--------------------
WaitForSingleObject(pthis->m_hEvent,INFINITE);
nsum = (1+pthis->m_nCalc)*pthis->m_nCalc/2;
//发送信号
emit pthis->signalValue(nsum);
}
return 0;
}
void Widget::on_pushButton_clicked()
{
//创建线程
if(!m_hThread)
m_hThread = CreateThread(0,0,&ThreadProc,this,0,0);
}
void Widget::on_radioButton_clicked()
{
m_nCalc =10;
SetEvent(m_hEvent);
}
void Widget::on_radioButton_2_clicked()
{
m_nCalc =100;
SetEvent(m_hEvent);
}
void Widget::on_radioButton_3_clicked()
{
m_nCalc = 1000;
SetEvent(m_hEvent);
}
void Widget::slotValue(int nvalue)
{
ui->lineEdit->setText(QString::number(nvalue));
}