操作系统 通过事件控制线程

本文详细描述了一种通过事件驱动的方式,在Qt应用中创建线程来计算从1到不同数目的和,并在用户点击相应按钮时更新界面的方法。通过Windows API创建事件,控制线程执行,展示了如何在多线程环境下高效管理计算任务。
摘要由CSDN通过智能技术生成

我们想要实现

 点击创建线程  点击上面的按钮 

1+...10:在右下角显示1+2+3...+10;

1+...100:在右下角显示1+2+3...+100;

1+...1000:在右下角显示1+2+3...+1000;

我么的思路是 先创建一个线程  在线程函数中 实现数据的计算 

然后把计算好的数传到右下角的输入框中

首先  我们先创建出事件

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    hsp=NULL;
    Flag=TRUE;

    num=0;
    connect(this,&Widget::setnum,this,&Widget::on_setnum);

    //创建事件
    m_hEvent=CreateEventA(0,0,0,0);//无安全属性  自动信号 初始信号为无信号  无名的事件

}

在主界面的析构里结束线程

首先我们在创建线程的槽函数中  创建一个线程

void Widget::on_pushButton_clicked()
{
    //创建线程

    if(! hsp)
    {
    hsp= CreateThread( 0,0,&ThreadProc,this,0,0);
    }

    //SuspendThread(hsp);

}

在线程函数中

便于管理 我们把它设在Widget类里

public:  
    static DWORD WINAPI ThreadProc(LPVOID lpParameter);
DWORD WINAPI Widget::ThreadProc(LPVOID lpParameter)
{
    Widget* pthis=(Widget*)lpParameter;
    int  nSum;

    while(pthis->Flag)
    {

        //等待事件信号
        WaitForSingleObject(pthis->m_hEvent,INFINITE);
            nSum=(1+pthis->num)*pthis->num/2;
            //发信号到主界面的控件上
            emit pthis->setnum(nSum);

            //SuspendThread(pthis->hsp);

        }
    return 0;


}

在线程函数中  我们无法直接对主界面进行操作  所以发信号

 emit pthis->setnum(nSum);

他的槽函数中对主界面进行操作

void Widget::on_setnum(int i)
{
    QString str=QString::number(i) ;
    ui->lineEdit->setText( str);
}

我们不想让线程函数中的while一直在计算  这样会大大占用资源  只想在我们点击对应按钮时才计算  所以加了一个判断条件


        //等待事件信号
        WaitForSingleObject(pthis->m_hEvent,INFINITE);

如果没有信号就不执行  有信号才执行 而且执行完  信号是自动信号 会把信号重新设置为无信号

这样一来 只需要在对应按钮的槽函数中设置响应的信号就可以实现事件对线程的控制

void Widget::on_radioButton_clicked()
{
    num=10;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);//将事件设置为有信号

}

void Widget::on_radioButton_2_clicked()
{
    num=100;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);
}

void Widget::on_radioButton_3_clicked()
{
    num=1000;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);
}

完整代码如下

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<windows.h>
#include <QString>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    static DWORD WINAPI ThreadProc(LPVOID lpParameter);

signals:
    void setnum(int );

public slots:
    void on_setnum(int );

private slots:
    void on_pushButton_clicked();



    void on_radioButton_clicked();

    void on_radioButton_2_clicked();

    void on_radioButton_3_clicked();

private:
    Ui::Widget *ui;
public:
    HANDLE hsp;
    bool Flag;
    HANDLE m_hEvent;
    int  num;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    hsp=NULL;
    Flag=TRUE;

    num=0;
    connect(this,&Widget::setnum,this,&Widget::on_setnum);

    //创建事件
    m_hEvent=CreateEventA(0,0,0,0);

}

Widget::~Widget()
{
    delete ui;
    Flag=FALSE;
    if(hsp)
    {
        if(WAIT_TIMEOUT==WaitForSingleObject(hsp,100));
        TerminateThread(hsp,-1);

        CloseHandle(hsp);
        hsp=NULL;
    }


}

DWORD WINAPI Widget::ThreadProc(LPVOID lpParameter)
{
    Widget* pthis=(Widget*)lpParameter;
    int  nSum;

    while(pthis->Flag)
    {

        //等待事件信号
        WaitForSingleObject(pthis->m_hEvent,INFINITE);
            nSum=(1+pthis->num)*pthis->num/2;
            //发信号到主界面的控件上
            emit pthis->setnum(nSum);

            //SuspendThread(pthis->hsp);

        }
    return 0;


}

void Widget::on_pushButton_clicked()
{
    //创建线程

    if(! hsp)
    {
    hsp= CreateThread( 0,0,&ThreadProc,this,0,0);
    }

    //SuspendThread(hsp);

}



    //控制上一个进程的结束
//    HANDLE hOpenEvent=OpenEventA(EVENT_ALL_ACCESS,0,"MyEvent");
//    if(hOpenEvent)
//    {
//        SetEvent(hOpenEvent);
//    }



void Widget::on_radioButton_clicked()
{
    num=10;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);
}

void Widget::on_radioButton_2_clicked()
{
    num=100;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);
}

void Widget::on_radioButton_3_clicked()
{
    num=1000;
    //ResumeThread(hsp);
    SetEvent(m_hEvent);
}


void Widget::on_setnum(int i)
{
    QString str=QString::number(i) ;
    ui->lineEdit->setText( str);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值