1.程序是计算机存储系统中的数据文件
- 源代码程序:文本文件,描述程序行为和功能
- 可执行程序:二进制文件,直接加载并执行
- 源代码程序------>编译------>可执行程序
2.进程
- 广义概念:程序关于某个数据集合的一次运行活动
- 狭义概念:程序加载到内存中执行后得到进程
3.进程与程序的区别
- 程序是硬盘中静态的文件,存储系统中的一段二进制表示
- 进程是内存中动态的运行实体,例数据段、代码段、PC指针等
4.程序和进程的联系
- 一个程序可能对应多个进程,一次程序多次运行,每次运行产生一个进程
- 一个进程可能包含多个程序,一个程序依赖于多个其他动态库
5.在当代操作系统中,资源分配的基本单位是进程,而CPU调度的基本单位是线程
6.线程的概念
- 进程内的一个执行单元
- 操作系统中的一个可调度的实体
- 进程中相对独立的一个控制流序列
- 执行时的现场数据和其他调度所需的信息
7.可执行程序加载执行后的步骤:
- 系统分配资源(内存、IO等)
- 将PC指向main函数入口地址
- 从PC指针包含的地址开始执行(第一个线程)
注:线程是进程使用CPU资源的基本单位
8.深入立即进程和线程
- 进程中可以存在多个线程共享进程资源
- 线程是被调用的执行单元,而进程不是调度单元
- 线程不能脱离进程单独存在,只能依赖于进程运行
- 线程有生命期,有诞生和死亡
- 任意线程都可以创建其他新的线程
9.Qt中通过QThread直接支持多线程
- QThread是一个跨平台的多线程解决方案
- QThread以简洁易用的方式实现多线程变成
- Qt中的线程以对象的形式被创建和使用,每一个线程对应一个QThread对象
10.QThread中的关键成员函数
- void run() 线程体函数,用于定义线程功能(执行流)
- void start() 启动函数,将线程入口地址设置为run函数
- void terminate() 强制结束线程
注:start() 是启动线程的"按钮",而 run() 是线程实际执行的"任务内容"
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
class MyThread : public QThread
{
protected:
void run()
{
qDebug() << objectName() << ":" << "run() begin";
for(int i=0; i<5; i++)
{
qDebug() << objectName() << ":" << i;
sleep(1);
}
qDebug() << objectName() << ":" << "run() end";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main() begin";
MyThread t;
t.setObjectName("t");
t.start();
MyThread tt;
tt.setObjectName("tt");
tt.start();
//消耗时间
for(int i=0; i<10000; i++)
{
for(int j=0; j<10000; j++)
{
}
}
qDebug() << "main() end";
return QCoreApplication::exec();
}
运行结果:
main() begin
"t" : run() begin
"tt" : run() begin
"t" : 0
"tt" : 0
main() end
"tt" : 1
"t" : 1
"t" : 2
"tt" : 2
"tt" : 3
"t" : 3
"tt" : 4
"t" : 4
"t" : run() end
"tt" : run() end
注意:在工程开发中terminate()是禁止使用的,terminate()会使得操作系统暴力终止线程,而不会考虑数据完整性,资源释放等问题,那么如何在代码中优雅终止线程
- run()函数执行结束是优雅终止线程的唯一方式
- 在线程类中增加标志变量m_toStop(volatile bool)
- 通过m_toStop的值判断是否需要从run()函数返回
使用m_toStop来终止
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
class Sample : public QThread
{
protected:
volatile bool m_toStop;
void run()
{
qDebug() << objectName() << ": begin";
int* p = new int[10000];
for(int i=0; !m_toStop && (i<10); i++)
{
qDebug() << objectName() << ":" << i;
p[i] = i * i * i;
msleep(500); //休息500ms
}
delete[] p;
qDebug() << objectName() << ": end";
}
public:
Sample()
{
m_toStop = false;
}
void stop()
{
m_toStop = true;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main begin:";
Sample t;
t.setObjectName("t");
t.start();
for(int i=0; i<100000; i++)
{
for(int j=0; j<100000; j++)
{
}
}
t.stop();
// t.terminate(); //强制终止
qDebug() << "main end";
return QCoreApplication::exec();
}
运行结果:
main begin:
main end
"t" : begin
"t" : end
使用terminate来终止
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
class Sample : public QThread
{
protected:
volatile bool m_toStop;
void run()
{
qDebug() << objectName() << ": begin";
int* p = new int[10000];
for(int i=0; i<10; i++)
{
qDebug() << objectName() << ":" << i;
p[i] = i * i * i;
msleep(500); //休息500ms
}
delete[] p;
qDebug() << objectName() << ": end";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main begin:";
Sample t;
t.setObjectName("t");
t.start();
t.terminate(); //强制终止
qDebug() << "main end";
return QCoreApplication::exec();
}
运行结果:
main begin:
main end