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


    我们想要实现

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

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

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

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

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

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

    首先  我们先创建出事件

    1. Widget::Widget(QWidget *parent)
    2. : QWidget(parent)
    3. , ui(new Ui::Widget)
    4. {
    5. ui->setupUi(this);
    6. hsp=NULL;
    7. Flag=TRUE;
    8. num=0;
    9. connect(this,&Widget::setnum,this,&Widget::on_setnum);
    10. //创建事件
    11. m_hEvent=CreateEventA(0,0,0,0);//无安全属性 自动信号 初始信号为无信号 无名的事件
    12. }

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

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

    1. void Widget::on_pushButton_clicked()
    2. {
    3. //创建线程
    4. if(! hsp)
    5. {
    6. hsp= CreateThread( 0,0,&ThreadProc,this,0,0);
    7. }
    8. //SuspendThread(hsp);
    9. }

    在线程函数中

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

    public:  
        static DWORD WINAPI ThreadProc(LPVOID lpParameter);
    1. DWORD WINAPI Widget::ThreadProc(LPVOID lpParameter)
    2. {
    3. Widget* pthis=(Widget*)lpParameter;
    4. int nSum;
    5. while(pthis->Flag)
    6. {
    7. //等待事件信号
    8. WaitForSingleObject(pthis->m_hEvent,INFINITE);
    9. nSum=(1+pthis->num)*pthis->num/2;
    10. //发信号到主界面的控件上
    11. emit pthis->setnum(nSum);
    12. //SuspendThread(pthis->hsp);
    13. }
    14. return 0;
    15. }

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

     emit pthis->setnum(nSum);

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

    1. void Widget::on_setnum(int i)
    2. {
    3. QString str=QString::number(i) ;
    4. ui->lineEdit->setText( str);
    5. }

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


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

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

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

    1. void Widget::on_radioButton_clicked()
    2. {
    3. num=10;
    4. //ResumeThread(hsp);
    5. SetEvent(m_hEvent);//将事件设置为有信号
    6. }
    7. void Widget::on_radioButton_2_clicked()
    8. {
    9. num=100;
    10. //ResumeThread(hsp);
    11. SetEvent(m_hEvent);
    12. }
    13. void Widget::on_radioButton_3_clicked()
    14. {
    15. num=1000;
    16. //ResumeThread(hsp);
    17. SetEvent(m_hEvent);
    18. }

    完整代码如下

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include
    5. #include
    6. QT_BEGIN_NAMESPACE
    7. namespace Ui { class Widget; }
    8. QT_END_NAMESPACE
    9. class Widget : public QWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. Widget(QWidget *parent = nullptr);
    14. ~Widget();
    15. static DWORD WINAPI ThreadProc(LPVOID lpParameter);
    16. signals:
    17. void setnum(int );
    18. public slots:
    19. void on_setnum(int );
    20. private slots:
    21. void on_pushButton_clicked();
    22. void on_radioButton_clicked();
    23. void on_radioButton_2_clicked();
    24. void on_radioButton_3_clicked();
    25. private:
    26. Ui::Widget *ui;
    27. public:
    28. HANDLE hsp;
    29. bool Flag;
    30. HANDLE m_hEvent;
    31. int num;
    32. };
    33. #endif // WIDGET_H
    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. Widget::Widget(QWidget *parent)
    4. : QWidget(parent)
    5. , ui(new Ui::Widget)
    6. {
    7. ui->setupUi(this);
    8. hsp=NULL;
    9. Flag=TRUE;
    10. num=0;
    11. connect(this,&Widget::setnum,this,&Widget::on_setnum);
    12. //创建事件
    13. m_hEvent=CreateEventA(0,0,0,0);
    14. }
    15. Widget::~Widget()
    16. {
    17. delete ui;
    18. Flag=FALSE;
    19. if(hsp)
    20. {
    21. if(WAIT_TIMEOUT==WaitForSingleObject(hsp,100));
    22. TerminateThread(hsp,-1);
    23. CloseHandle(hsp);
    24. hsp=NULL;
    25. }
    26. }
    27. DWORD WINAPI Widget::ThreadProc(LPVOID lpParameter)
    28. {
    29. Widget* pthis=(Widget*)lpParameter;
    30. int nSum;
    31. while(pthis->Flag)
    32. {
    33. //等待事件信号
    34. WaitForSingleObject(pthis->m_hEvent,INFINITE);
    35. nSum=(1+pthis->num)*pthis->num/2;
    36. //发信号到主界面的控件上
    37. emit pthis->setnum(nSum);
    38. //SuspendThread(pthis->hsp);
    39. }
    40. return 0;
    41. }
    42. void Widget::on_pushButton_clicked()
    43. {
    44. //创建线程
    45. if(! hsp)
    46. {
    47. hsp= CreateThread( 0,0,&ThreadProc,this,0,0);
    48. }
    49. //SuspendThread(hsp);
    50. }
    51. //控制上一个进程的结束
    52. // HANDLE hOpenEvent=OpenEventA(EVENT_ALL_ACCESS,0,"MyEvent");
    53. // if(hOpenEvent)
    54. // {
    55. // SetEvent(hOpenEvent);
    56. // }
    57. void Widget::on_radioButton_clicked()
    58. {
    59. num=10;
    60. //ResumeThread(hsp);
    61. SetEvent(m_hEvent);
    62. }
    63. void Widget::on_radioButton_2_clicked()
    64. {
    65. num=100;
    66. //ResumeThread(hsp);
    67. SetEvent(m_hEvent);
    68. }
    69. void Widget::on_radioButton_3_clicked()
    70. {
    71. num=1000;
    72. //ResumeThread(hsp);
    73. SetEvent(m_hEvent);
    74. }
    75. void Widget::on_setnum(int i)
    76. {
    77. QString str=QString::number(i) ;
    78. ui->lineEdit->setText( str);
    79. }

  • 相关阅读:
    【刷题篇】贪心算法(二)
    浏览器缓存机制
    [Q&A]AttributeError: module ‘signal‘ has no attribute ‘SIGALRM‘
    常见的项目管理问题有哪些?
    力扣:88. 合并两个有序数组(Python3)
    BOA服务器(一):简介
    Academic accumulation|英文文献速读
    Vue.js的单向数据流:让你的应用更清晰、更可控
    迪杰斯特拉算法(C++)
    HTTP协议详解
  • 原文地址:https://blog.csdn.net/van9527/article/details/126175718