首页 > 其他分享 >OpenGL在QT中的管理

OpenGL在QT中的管理

时间:2023-07-13 11:56:51浏览次数:36  
标签:float 1.0 QT 管理 0.0 void OpenGL 0.5 include

一、 设计思路

1. 用例图管理

 

2.困惑点:

  (1) 在程序编写中,为什么主程序的Shader可以关联到model类中的数据。

    解决:在加载数据方面,利用VBO、VAO等,已经将数据通过处理推到GPU上。

二、 代码实现

GLHeader.h

#pragma once
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
#include <QOpenGLExtraFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLContext>
#ifdef _DEBUG
#include <QOpenGLDebugLogger>
#endif

#define GLFuncName QOpenGLExtraFunctions
View Code

main.cpp

#include <qapplication.h>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
View Code

widget.h

#pragma once
#ifndef WIDGET_H
#define WIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture>
#include <QTimer>
#include <QTime>
#include <QtMath>
#include <memory>
#include "model.h"
#include "Camera.h"

class Widget : public QOpenGLWidget, public QOpenGLExtraFunctions
{
    Q_OBJECT

public:
    Widget(QWidget* parent = 0);
    ~Widget();
protected:
    virtual void initializeGL() override;
    virtual void resizeGL(int w, int h) override;
    virtual void paintGL() override;

    virtual bool event(QEvent* e) override;
private:

    std::shared_ptr<model> m_cube = nullptr;
    QVector<QVector3D> cubePositions;
    QOpenGLShaderProgram shaderProgram;
    QOpenGLVertexArrayObject VAO;

    QTimer timer;

    //QVector3D cameraPos;
    //QVector3D cameraTarget;
    //QVector3D cameraDirection;
    //QVector3D cameraRight;
    //QVector3D cameraUp;

    Camera camera;
};

#endif // WIDGET_H
View Code

widget.cpp

#include "widget.h"
#include <QtMath>

Widget::Widget(QWidget* parent)
    : QOpenGLWidget(parent)
    ,camera(this)
{
    cubePositions = {
      { 0.0f,  0.0f,  0.0f  },
      { 2.0f,  5.0f, -15.0f },
      {-1.5f, -2.2f, -2.5f  },
      {-3.8f, -2.0f, -12.3f },
      { 2.4f, -0.4f, -3.5f  },
      {-1.7f,  3.0f, -7.5f  },
      { 1.3f, -2.0f, -2.5f  },
      { 1.5f,  2.0f, -2.5f  },
      { 1.5f,  0.2f, -1.5f  },
      {-1.3f,  1.0f, -1.5f  },
    };

    timer.setInterval(18);
    connect(&timer, &QTimer::timeout, this, static_cast<void (Widget::*)()>(&Widget::update));
    timer.start();
}

Widget::~Widget()
{
    makeCurrent();
    m_cube = nullptr;
    doneCurrent();
}

void Widget::initializeGL()
{
    this->initializeOpenGLFunctions();        //初始化opengl函数
    m_cube = std::make_shared<model>(this);
    camera.init();
}

void Widget::resizeGL(int w, int h)
{
    this->glViewport(0, 0, w, h);                //定义视口区域
}

void Widget::paintGL()
{
    this->glClearColor(0.1f, 0.5f, 0.7f, 1.0f);  //设置清屏颜色
    this->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);       //清除颜色缓存

    float time = QTime::currentTime().msecsSinceStartOfDay() / 1000.0;
    shaderProgram.bind();                     //使用shaderProgram着色程序

    QMatrix4x4 projection;
    projection.perspective(45.0f, width() / (float)height(), 0.1f, 100.0f);

    QOpenGLVertexArrayObject::Binder{ &VAO };

    for (unsigned int i = 0; i < 10; i++) {
        QMatrix4x4 model;
        model.translate(cubePositions[i]);
        model.rotate(180 * time + i * 20.0f, QVector3D(1.0f, 0.5f, 0.3f));
        m_cube->draw(shaderProgram, model, camera.getView(), projection);
    }
}

bool Widget::event(QEvent* e)
{
    camera.handle(e);
    return QWidget::event(e);   //调用父类的事件分发函数
}
View Code

model.h

#pragma once
#include"GLHeader.h"
#include <QOpenGLVertexArrayObject>
#include <QTime>

class model
{
public:
    model(GLFuncName* func);
    ~model();

    void draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project);

    QVector<float> vertices;
    QVector<QVector3D> cubePositions;
    QOpenGLShaderProgram myprogram;

    QOpenGLBuffer VBO;
    QOpenGLVertexArrayObject VAO;
    QOpenGLTexture texture;
    QOpenGLTexture texture1;

private:
    void initBuffer();
    void initShader();
    void initTexture();

private:
    GLFuncName* m_func;

};
View Code

model.cpp

#include "model.h"

model::model(GLFuncName* func)
    : m_func(func)
    , texture(QOpenGLTexture::Target2D)
    , texture1(QOpenGLTexture::Target2D)
    , VBO(QOpenGLBuffer::VertexBuffer)
{
    initShader();
    initBuffer();
    initTexture();
}

model::~model()
{
    VBO.destroy();
    texture.destroy();
    texture1.destroy();
}

void model::draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project)
{
    program.removeAllShaders();
    program.addShaderFromSourceFile(QOpenGLShader::Vertex, "./triangle.vert");
    program.addShaderFromSourceFile(QOpenGLShader::Fragment, "./triangle.frag");

    if (!program.link()) {
        qWarning() << program.log();
        return;
    }
    if (!program.bind()) {
        qWarning() << program.log();
        return;
    }

    program.setUniformValue("projection", project);
    program.setUniformValue("view", view);
    program.setUniformValue("model", model);

    texture.bind(0);                                        //将texture绑定到纹理单元0
    program.setUniformValue("ourTexture", 0);         //让ourTexture从纹理单元0中获取纹理数据

    texture1.bind(1);                                       //将texture绑定到纹理单元1
    program.setUniformValue("ourTexture1", 1);        //让ourTexture从纹理单元1中获取纹理数据

    m_func->glDrawArrays(GL_TRIANGLES, 0, 36);

}

/// <summary>
/// 数组初始化,着色器绑定
/// </summary>
void model::initBuffer()
{
    VBO.create();       //生成VBO对象
    vertices = {
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    QOpenGLVertexArrayObject::Binder{ &VAO };


    VBO.bind();         //将VBO绑定到当前的顶点缓冲对象(QOpenGLBuffer::VertexBuffer)中

    //将顶点数据分配到VBO中,第一个参数为数据指针,第二个参数为数据的字节长度
    VBO.allocate(vertices.data(), sizeof(float) * vertices.size());


    //设置顶点解析格式,并启用顶点
    myprogram.setAttributeBuffer("aPos", GL_FLOAT, 0, 3, sizeof(GLfloat) * 5);
    myprogram.enableAttributeArray("aPos");
    myprogram.setAttributeBuffer("aTexCoord", GL_FLOAT, sizeof(GLfloat) * 3, 2, sizeof(GLfloat) * 5);
    myprogram.enableAttributeArray("aTexCoord");

    m_func->glEnable(GL_DEPTH_TEST);

}

/// <summary>
/// 着色器编写
/// </summary>
void model::initShader()
{
    if (!myprogram.addShaderFromSourceFile(QOpenGLShader::Vertex, "./triangle.vert")) {     //添加并编译顶点着色器
        qDebug() << "ERROR:" << myprogram.log();    //如果编译出错,打印报错信息
    }
    if (!myprogram.addShaderFromSourceFile(QOpenGLShader::Fragment, "./triangle.frag")) {   //添加并编译片段着色器
        qDebug() << "ERROR:" << myprogram.log();    //如果编译出错,打印报错信息
    }
    if (!myprogram.link()) {                      //链接着色器
        qDebug() << "ERROR:" << myprogram.log();    //如果链接出错,打印报错信息
    }
}
/// <summary>
/// 纹理初始化
/// </summary>
void model::initTexture()
{
    texture.setData(QImage("./RC.jpg").mirrored());
    texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
    texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
    texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);

    texture1.setData(QImage(":/sea.jpg").mirrored());
    texture1.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
    texture1.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
    texture1.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
}
View Code

Camera.h

#pragma once
#include <QSet>
#include <QVector3D>
#include <QEvent>
#include <QWidget>
#include <QtMath>
#include <QMatrix4x4>
#include <QKeyEvent>
#include <QTime>

class Camera
{
public:
    Camera(QWidget* widget);
    float getMoveSpeed() const;
    void setMoveSpeed(float value);
    float getSensitivity() const;
    void setSensitivity(float value);
    float getYaw() const;
    void setYaw(float value);
    float getPitch() const;
    void setPitch(float value);
    QVector3D getCameraPos() const;
    void setCameraPos(const QVector3D& value);
    void init();                    //初始化摄像机
    void handle(QEvent* event);     //处理窗口事件
    QMatrix4x4 getView() const;     //获取观察矩阵
    qreal m_aspect = 45;
    QQuaternion m_rotation;

private:
    QWidget* widget;

    float yaw = -90;                  //偏航角
    float pitch = 0;                //俯视角
    float sensitivity;          //鼠标灵敏度

    QPoint m_last;
    QVector2D m_mousePressPosition;
    bool m_keys[1024] = { false };
    QVector3D m_rotationAxis;
    float m_angularSpeed = 0;
    qreal m_elapsed = 100;


    QVector3D cameraPos;        //摄像机初始位置
    QVector3D cameraDirection;  //摄像机方向
    QVector3D cameraTarget;
    QVector3D cameraRight;      //摄像机右向量
    QVector3D cameraUp;         //摄像机上向量

    float moveSpeed;    //控制移动速度
    QSet<int> keys;     //记录当前被按下按键的集合

    int timeId;         //定时器id:此定时器用于完成键盘移动事件
    float deltaTime;    // 当前帧与上一帧的时间差
    float lastFrame;    // 上一帧的时间

    QMatrix4x4 view;    //观察矩阵

};
View Code

Camera.cpp

#include "Camera.h"

Camera::Camera(QWidget* widget)
    : widget(widget)
    , yaw(0)
    , pitch(0)
    , sensitivity(0.005f)
    , cameraPos(0.0f, 0.0f, 10.0f)
    , cameraDirection(0.0f, 0.0f, -1.0f)
    , cameraTarget(0.0f, 0.0f, 0.0f)
    , cameraRight(QVector3D::crossProduct({ 0.0f,1.0f,0.0f }, cameraDirection))
    , cameraUp(QVector3D::crossProduct(cameraDirection, cameraRight))
    , moveSpeed(0.5f)
    , timeId(0)
{

}

float Camera::getMoveSpeed() const
{
    return moveSpeed;
}

void Camera::setMoveSpeed(float value)
{
    moveSpeed = value;
}

float Camera::getSensitivity() const
{
    return sensitivity;
}

void Camera::setSensitivity(float value)
{
    sensitivity = value;
}

float Camera::getYaw() const
{
    return yaw;
}

void Camera::setYaw(float value)
{
    yaw = value;
}

float Camera::getPitch() const
{
    return pitch;
}

void Camera::setPitch(float value)
{
    pitch = value;
}

QVector3D Camera::getCameraPos() const
{
    return cameraPos;
}

void Camera::setCameraPos(const QVector3D& value)
{
    cameraPos = value;
}

void Camera::handle(QEvent* e)
{
    //关闭鼠标跟踪才能正确显示鼠标点击、移动和释放
    if (e->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        m_last = event->pos();                    //获取当前位置
        m_mousePressPosition = QVector2D{ event->localPos() };  //以float型存储当前位置
    }
    else if (e->type() == QEvent::MouseMove)
    {
        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        QPointF diff = event->pos() - m_last;     //计算位置
        m_last = event->pos();                    //更新当前鼠标位置

        qreal sensitivity = 0.05;                 //灵敏度
        qreal xoffset = diff.x() * sensitivity;   //计算x偏移向量
        qreal yoffset = diff.y() * sensitivity;   //计算y偏移向量

        //弧度与角度的转换会使得物体的平移产生问题
        yaw += xoffset;
        pitch += yoffset;
        if (pitch > 89.0)                                        //将俯视角限制到[-89°,89°],89°约等于1.55
            pitch = 89.0;
        if (pitch < -89.0)
            pitch = -89.0;

        QVector3D front;
        front.setX(cos(qDegreesToRadians(yaw)) * cos(qDegreesToRadians(pitch)));
        front.setY(sin(qDegreesToRadians(pitch)));
        front.setZ(sin(qDegreesToRadians(yaw)) * cos(qDegreesToRadians(pitch)));
        cameraDirection = front.normalized();

        view.setToIdentity();
        view.lookAt(cameraPos, cameraPos + cameraDirection, cameraUp);
        
    }
    else if (e->type() == QEvent::Wheel)
    {
        QWheelEvent* event = static_cast<QWheelEvent*>(e);
        int offset = event->angleDelta().y() < 0 ? -1 : 1;
        qreal speed = 10;
        if (1 <= m_aspect + offset * speed && m_aspect + offset * speed <= 45) {
            m_aspect = m_aspect + offset * speed;
        }
        event->accept();
    }
    else if (e->type() == QEvent::MouseButtonRelease)
    {
        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        QVector2D diff = QVector2D{ event->localPos() } - m_mousePressPosition;
        QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized();

        float acc = diff.length() / 100.0f;
        m_rotationAxis = (m_rotationAxis * m_angularSpeed + n * acc).normalized();

        m_angularSpeed += acc;                 //获取当前位置
    }
    else if (e->type() == QEvent::Timer) {
        float cameraSpeed = moveSpeed * m_elapsed / 1000.0;
        if (keys.contains(Qt::Key_W))                            //前
        {
            cameraPos += cameraSpeed * cameraDirection;
        }
        if (keys.contains(Qt::Key_S))                           //后
        {
            cameraPos -= cameraSpeed * cameraDirection;
        }
        if (keys.contains(Qt::Key_A))                           //左
        {
            cameraPos += QVector3D::crossProduct(cameraDirection, cameraUp).normalized() * cameraSpeed;
        }
        if (keys.contains(Qt::Key_D))                           //右
        {
            cameraPos -= QVector3D::crossProduct(cameraDirection, cameraUp).normalized() * cameraSpeed;
        }
        if (keys.contains(Qt::Key_Space))                       //上浮
        {
            cameraPos.setY(cameraPos.y() + cameraSpeed);
        }
        if (keys.contains(Qt::Key_Shift))                       //下沉
        {
            cameraPos.setY(cameraPos.y() - cameraSpeed);
        }
        view.setToIdentity();
        view.lookAt(cameraPos, cameraPos + cameraDirection, cameraUp);
    }
    else if (e->type() == QEvent::KeyPress) {
        //isAutoRepeat用于判断此按键的来源是否是长按
        QKeyEvent* event = static_cast<QKeyEvent*>(e);
        keys.insert(event->key());                              //添加按键
        if (!event->isAutoRepeat() && timeId == 0) {                  //如果定时器未启动,则启动定时器
            timeId = widget->startTimer(1);
        }
    }
    else if (e->type() == QEvent::KeyRelease) {
        QKeyEvent* event = static_cast<QKeyEvent*>(e);
        keys.remove(event->key());
        if (!event->isAutoRepeat() && timeId != 0 && keys.empty()) {    //当没有按键按下且定时器正在运行,才关闭定时器
            widget->killTimer(timeId);
            timeId = 0;                                          //重置定时器id
        }
    }
}

void Camera::init()
{
    view.lookAt(cameraPos, cameraPos + cameraDirection, cameraUp);
    widget->activateWindow();                 //激活窗口
    widget->setFocus();

}

QMatrix4x4 Camera::getView() const
{
    return view;
}
View Code

triangle.frag

#version 330 core
out vec4 FragColor;
 
in vec2 TexCoord;
 
uniform sampler2D ourTexture;
uniform sampler2D ourTexture1;
void main()
{
    FragColor = mix(texture(ourTexture, TexCoord), texture(ourTexture1, TexCoord), 0.4);
}
View Code

triangle.vert

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
 
void main()
{
    // 注意乘法要从右向左读
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = aTexCoord;
}
View Code

引用:https://blog.csdn.net/qq_40946921/article/details/105902185

     github中的天空模型,忘记网址。

 

标签:float,1.0,QT,管理,0.0,void,OpenGL,0.5,include
From: https://www.cnblogs.com/wxd-/p/17549548.html

相关文章

  • 可视化大屏,提升水灾应急管理效能
    随着气候变化和城市化进程的加剧,暴雨天气引发的水灾风险日益凸显。在面对这种自然灾害时,如何高效、及时地应对、减轻损失成为了当务之急。水灾应急管理平台的可视化大屏为相关部门和决策者提供了实时、全面的信息展示和决策支持,大大提升了应急管理的效能。  可视化大屏能够实......
  • EasyCVR平台Ehome协议接入,设备管理中出现新增通道按钮的问题优化
    EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。有用户反馈,通过海康Ehome接入的设备,在设备管理中出现了新......
  • Java虚拟机(JVM):第五幕:自动内存管理 - HotSpot算法细节以及低延迟垃圾收集器
    一、HotSpot算法细节1、根节点枚举:所有的收集器在根节点枚举的时候,必须暂停用户线程,同时要保证一致性的快照中得以进行。一致性:整个枚举期间执行子系统看起来就像是冻结在某一个时间点上,不会出现分析过程中,根节点的对象应用关系还在不断变化的情况。2、安全点:用户程序执......
  • Proton 推出开源密码管理器,兼身份管理器
    Proton是由来自欧洲核研究组织(CERN)的科学家于2014年在瑞士日内瓦创立的一家公司,其最知名的应该就是电子邮件服务ProtonMail,主打端到端加密、安全和隐私保护。Proton由科学家领导,其中包括万维网的发明者TimBerners-Lee。该公司曾于今年4月份宣布推出一个新的......
  • Proton 推出开源密码管理器,兼身份管理器
    Proton是由来自欧洲核研究组织(CERN)的科学家于2014年在瑞士日内瓦创立的一家公司,其最知名的应该就是电子邮件服务ProtonMail,主打端到端加密、安全和隐私保护。Proton由科学家领导,其中包括万维网的发明者TimBerners-Lee。该公司曾于今年4月份宣布推出一个新的......
  • Jenkins远程管理K8S集群实现自动POD部署
    Jenkins远程管理K8S集群实现自动POD部署大致思路修改.kube/config文件,增加新集群的context建立隧道将集群控制端口映射到Jenkins服务器本地端口测试jenkin切换到新context是否能控制该集群新集群配置对接Harbor仓库测试helm部署podJenkins测试配置流水线自动发版1.......
  • PyQt,PySide2中嵌入Matplotlib图像
    PyQt,PySide2中嵌入Matplotlib图像方式1使用QtDesigner新建一个MainWindow,在此之上创建一个VerticalLayout。importsysimportnumpyasnpfromPySide2.QtUiToolsimportQUiLoaderfromPySide2.QtWidgetsimportQApplicationimportmatplotlibmatplotlib.use("Qt5......
  • Linux 软件包管理 笔记
    Linux软件包管理: rmp命令:rmp-q软件名#查询是都安装此软件rpm-pl软件名#查询软件安装位置rpm-ivh软件名-版本信息#安装软件包,安装时需要提供......
  • 跨平台GUI开发技术:QT,GTK+, C#(WinForm/WPF), Java(Swing/AWT/JavaFX), Electron, comp
    1.Compose-multiplatformJetbrian推出的跨全平台开发组件技术,android/ios/desktop(win,linux,mac)/web,目前生态完善中,还不够成熟,但有潜力,支持原生接口调用,kotlin作为主要语言。https://www.jetbrains.com/zh-cn/lp/compose-multiplatformhttps://github.com/JetBrains/compose-......
  • 计算机操作系统-2-处理器管理
    Lecture2-处理器管理处理器管理是操作系统的重要组成部分处理器负责管理、调度和分配计算机系统的重要资源,并控制程序执行处理器管理中最重要的是处理器调度,即进程调度,也就是控制、协调进程对处理器的竞争。进程与线程进程是资源分配和管理的单位线程是处理器调度的基本单......