Windowns操作系统:进程线程(Qt)

进程:执行任务独立的集合,分配资源的基本单位              
线程:隶属于进程的一部分,分配CPU的基本单位(轮换时间片的基本单位) 
线程的运行方式:1.并发:多个执行命令交替执行             
             2.并行:多个执行命令同时执行        
                                    
线程组成部分:1.线程区(堆栈区),用来存放线程所需要的临时的、局部资源
            2.内核对象:计数器(2)  关闭句柄-1 线程退出-1
             挂起计数器  
             信号    
                    无信号:线程存在
                    有信号:线程不存在
线程挂起和恢复:
SuspendThread(m_hThread);挂起线程 
 ResumeThread(m_hThread);恢复线程                            
退出方式:先退出 若不能退出 则杀死       

线程的局部存储(TLS)           
                                    
线程栈私有  堆是共有的                        
同一进程中的线程间通信 :全局变量 信号和槽  事件          
跨进程通信: 事件                          
用户线程 内核线程    
单线程:洗衣服 做饭   
多线程:一起来      
提高工作的密集度来提高效率
1-1          
n-1          
n-m(n < m)   


多线程访问共享资源并发问题                                                                                                
解决方案:线程同步                                                                                                    
方式:1.原子访问:同一时刻只允许一个线程访问资源 volatile 防止编译优化,对特殊地址的稳定访问 直接操作内存                                                  
     2.临界区(关键段)(用户模式下的线程同步):同一时刻只允许一个线程访问代码段                                                                 
        1)直接阻塞                                                                                               
        2)旋转锁:如果发现关键段里面有其他线程,他会等待一段时间,时间内若关键段的线程出现在锁外,他就进得去,否则处于死锁状态                                         
        3)非阻塞:能进就进 不耽误干别的                                                                                    
     3.内核对象:同一时刻只允许一个线程访问代码段                                                                                 
        1)互斥量 同一时刻只允许一个线程访问代码段  初始拥有权                                                                        
        2)事件   同一时刻只允许一个线程访问代码段  人工                                                                          
        3) 信号量 同一时刻允许指定个数的线程访问代码段                                                                            
                                                                                                             
     内核对象与关键段的区别:1.安全灵活:内核对象 (任意控制阻塞时间)(当拥有内核对象的这个线程被杀死,这个内核对象会被释放,关键段不可以,若被锁了,锁会被一直占用)                      
                         2.作用范围:内核对象可以跨进程 临界区:同一进程                                                           
                         3.效率:临界区                                                                            

#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();
public:
    QTimer* pTimer;
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

signals:
    void signalSetValue(int);
public slots:
    void SlotSetValue(int);

private:
    Ui::Widget *ui;
public:
    HANDLE m_hThread;
    bool m_bFlag;
};
#endif // WIDGET_H
#include "widget.h"

#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    m_bFlag = true;
    m_hThread = nullptr;
    ui->setupUi(this);
    connect(this,&Widget::signalSetValue,this,&Widget::SlotSetValue);
}

Widget::~Widget()
{
    delete ui;
}

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    Widget* pThis = (Widget*)lpParameter;
        for(int i; i <= 100 && pThis->m_bFlag == true; i++)
        {
            //向主线程发送信号i
            emit pThis->signalSetValue(i);
            //pThis->ui->progressBar->setValue(i);
            Sleep(100);
            i%=100;
        }
    return 0;
}

void Widget::on_pushButton_clicked()
{
    if(!m_hThread)
    {
        m_bFlag = true;
        m_hThread = CreateThread(0,//线程安全属性
                     0,//线程栈的大小
                     &ThreadProc,//线程函数
                     this,//线程参数
                     0,//创建标志  0  立即运行 CREATE_SUSPENDED  挂起
                     0 //线程Id
                     );
    }

    else
        ResumeThread(m_hThread);
//    SuspendThread(m_hThread);//挂起线程
//    ResumeThread(m_hThread);//恢复线程


}

void Widget::SlotSetValue(int value)
{
    ui->progressBar->setValue(value);
}

void Widget::on_pushButton_2_clicked()
{
    SuspendThread(m_hThread);//挂起线程
}

void Widget::on_pushButton_3_clicked()
{
    //1.正常退出
    m_bFlag = false;
    //2.强制杀死
    //TerminateThread(m_hThread,-1);
    //如果能正常退出就正常退出,若不能则强制杀死
    //如何判断是否退出?--若线程为无信号代表线程存在,则强制杀死
    
    
    if(m_hThread)
    {
        if(WAIT_TIMEOUT == WaitForSingleObject(m_hThread,100))
        {
            TerminateThread(m_hThread,-1);
        }
        CloseHandle(m_hThread);
        m_hThread = nullptr;
    }
    ui->progressBar->setValue(0);
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值