kvm线程-001

KVM具有独立于机器的、可移植的线程模型,可以独立于Java语言运行.

其变化如下:

1.0之前

使用了一个简单的循环调度模型,其中系统中的所有活动线程都存储在循环列表中.

列表中的线程根据每个任务的Java级优先级,一个接一个地执行。在实现级别,线程优先级只是一个整数,它告诉解释器在下一个线程切换发生之前,线程可以执行多少原语。在每个字节码执行之后,线程的“Timeslice”计数器将递减。当时间片变为零时,将强制执行线程切换。一些I/O原语也可以启动线程切换。

1.0

加入了异步(非阻塞)I/O。

另一个目标是引入轻松实现替代调度机制的能力,但不太彻底地改变现有系统。

在最初的系统环境中,许多地方发生了切换。现在,它只在解释器调度循环的顶部完成。在原始版本中,可运行的线程与当前正在执行的线程一起保存在循环列表中。现在,当线程开始执行时,每个线程都会从可运行线程的循环列表中删除,当线程被阻塞时,会返回到循环列表中。

变量up已重命名为当前线程,并指向当前正在执行的线程。一个新的变量runnable threads指向可运行线程的循环列表。

suspendThread() 方法有所改变.

它以前有一个要挂起哪个线程的参数,但在任何情况下都不能挂起,所以该参数已被删除。这个例程用于执行上下文切换,但现在它只将currentThread置零,并调用一个名为signalTimeToReschedule()的新函数,该函数向解释器发出信号,表示在执行下一个字节码之前应该重新调度VM。

为解释器提供了一个新的函数istimeToReschedule()来测试这种情况,并调用了一个新的函数reschedule()来测试这种情况。解释器字节码调度循环顶部的代码现在是:

if (isTimeToReshedule()) {
         reschedule();
   }

isTimeToReshedule() 为宏,宏展开后为: Timeslice-- == 0.signalTimeToReschedule()也会宏,其只是将Timeslice 设置为0.

并定义了如下方法:

  1. startThread()

    标记线程存活,但是是暂停状态

  2. resumeThread()

    此函数将线程放回可运行线程列表(runnablethreads),如果激活的线程的优先级高于当前执行的线程的优先级,也将调用signalTimeToReschedule()。

  3. BuildThread()

    现在,这会将所有新线程添加到另一个名为all threads的活动线程列表中。此列表由垃圾收集器使用。

  4. DismantleThread()

    从AllThreads 中移除

  5. stopThread()

    此函数与buildThread()的逻辑相反。它挂起线程并调用Dismantlethread()。

  6. resumeThread()

    这将替换使用ActivateThread()重新启动挂起的线程。

  7. isActivated()

    在调用这个例程之前,必须测试currentThread是否为非空

  8. HandleEvent()

    因为原始handleEvent例程调用了ActivateThread,所以它不需要任何更改(isActivated()的调用约定除外)。 但是,返回参数的含义现在略有不同,这意味着向runnablethreads添加了一个新线程,而不是它只是切换了上下文。

  9. SwitchThread()

    switchthread现在只从reschedule()调用。当前线程可以指向线程,也可以不指向线程。如果这样,我们会像以前一样通过runnablethreads列表旋转线程。如果它为空并且runnablethreads列表为空,则函数返回false,并且reschedule()必须决定要做什么。

  10. JLT_Yield()

只在signalTimeToReschedule()中调用

此外,还支持了异步i/0.

1.0.3

kvm 1.0.3有一个新的monitor/synchronization实现。


线程模型

在kvm中内部,为每个线程实例化以下结构之一:

  • THREAD : 是一种内部(VM级)结构,用于存储独立于Java级的东西来实现抢占任务切换的必要信息。活动线程单独链接到包含系统中所有活动线程的线性列表。
  • JAVATHREAD: JAVATHREAD被映射到Java类“Thread.java”中定义的实例结构。它是从线程引用的。

为什么定义这两个结构? 其原因是为了便于移植,kvm希望保持线程系统实现与Java语言无关。

其中THREAD定义如下:

struct threadQueue {
    THREAD nextAliveThread;  /*  alive线程队列 */
    THREAD nextThread;       /*  运行或等待线程队列 */
    JAVATHREAD javaThread;   /*  包含java 级别的线程信息 */
    long   timeslice;        /*  从Java级线程优先级计算而来*/
    STACK stack;             /*   该线程的执行栈*/

    /*
     * 以下四个变量用于在线程可运行时存储线程的虚拟机寄存器(=active,但不是当前给定的处理器时间)。
     * 为了方便垃圾收集,我们将指向执行堆栈的指针存储为偏移量,而不是实际指针。
     * */
    BYTE* ipStore;           /*   程序计数器*/
    FRAME fpStore;           /*  帧*/
    cell* spStore;           /*  sp*/
    cell* nativeLp;          /* 在KNI的调用中用来访问本地变量*/

    MONITOR monitor;         /* 当前线程的monitor*/
    short monitor_depth;

    THREAD nextAlarmThread;  /* 在当前队列中的下一个线程 */
    long   wakeupTime[2];    /*  我们不能要求堆对象的8字节对齐 */
    void (*wakeupCall)(THREAD); /*  线程唤醒时调用 */
    struct {
        int depth;
        long hashCode;
    } extendedLock;          /*  在FASTLOCK时使用*/

    char* pendingException;  /* 线程将要抛出异常的类名 */
    char* exceptionMessage;  /*  要抛出异常的信息 */

    enum {
        THREAD_JUST_BORN = 1,     /* 还没有启动 */
        THREAD_ACTIVE = 2,        /* 当前正在运行,或者在等待运行的队列中 */
        THREAD_SUSPENDED = 4,     /* 等待monitor或者alarm */
        THREAD_DEAD = 8,          /* 线程退出 */
        THREAD_MONITOR_WAIT = 16,
        THREAD_CONVAR_WAIT = 32,
        THREAD_DBG_SUSPENDED = 64
    } state; // 线程状态定义
    bool_t isPendingInterrupt;    /* Don't perform next sleep or wait */

#if ENABLE_JAVA_DEBUGGER
    bool_t isStepping;      
    bool_t isAtBreakpoint;
    bool_t needEvent;
    CEModPtr debugEvent;

    ByteCode nextOpcode;
    struct singleStep_mod stepInfo;
    int debugSuspendCount; 
#endif /* ENABLE_JAVA_DEBUGGER */

};

JAVATHREAD定义如下:

struct javaThreadStruct {    /* (A true Java object instance) */

    COMMON_OBJECT_INFO(INSTANCE_CLASS)
    long       priority;     /*  线程的优先级*/
    THREAD     VMthread;     /* 执行vm thread  */
    INSTANCE   target;       /* 执行run的对象 */
    SHORTARRAY name;         /*  线程名称*/
};
### 使用 KVM 和 QEMU 创建虚拟机 #### 硬件与软件环境准备 在使用 KVM 和 QEMU 创建虚拟机之前,需确认硬件支持虚拟化技术并已启用。可以通过运行以下命令验证 CPU 是否具备虚拟化扩展功能: ```bash egrep -c '(vmx|svm)' /proc/cpuinfo ``` 如果返回值大于零,则表示硬件支持虚拟化[^1]。 对于 Linux 平台上的 KVM 配置,还需要确保操作系统内核启用了 KVM 模块。可以执行以下命令加载模块并检查其状态: ```bash sudo modprobe kvm-intel # 对于 Intel 处理器 sudo modprobe kvm-amd # 对于 AMD 处理器 lsmod | grep kvm # 检查模块是否成功加载 ``` #### 安装必要工具 为了构建基于 KVM 的虚拟机,需要安装 `qemu-kvm` 及其他辅助组件(如 `libvirt`)。以下是典型的操作系统中的安装方式: - **Debian/Ubuntu**: ```bash sudo apt update && sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager ``` - **CentOS/RHEL/Fedora**: ```bash sudo yum groupinstall 'Virtualization Host' sudo systemctl enable --now libvirtd.service ``` 完成上述步骤后,可以在 `/usr/bin/` 或 `/usr/local/bin/` 中找到所需的工具集,例如 `qemu-system-x86_64` 和 `qemu-img`[^4]。 #### 创建虚拟硬盘镜像 利用 `qemu-img` 命令创建一块用于存储 Guest OS 数据的虚拟磁盘文件。下面是一个示例命令,它将生成大小为 20GB 的 qcow2 格式的磁盘图像: ```bash qemu-img create -f qcow2 my_vm_disk.qcow2 20G ``` #### 启动虚拟机实例 一旦准备工作完毕,即可调用 `qemu-system-x86_64` 来引导新定义好的虚拟机。假设已经准备好 ISO 文件作为安装介质,那么完整的启动参数可能如下所示: ```bash qemu-system-x86_64 \ -enable-kvm \ # 启用 KVM 加速 -m 4096 \ # 设置内存容量 (单位 MB) -cpu host \ # 将主机物理处理器特性传递给客户机 -smp cores=4,threads=1 \ # 分配逻辑核心数以及线程数量 -drive file=my_vm_disk.qcow2,format=qcow2 \ -boot d \ # 设定从光驱设备优先启动 -cdrom path_to_iso_file.iso\ -vga std # 显示适配器类型指定标准 VGA 控制器 ``` 注意:实际应用过程中应依据具体需求调整资源配置策略以避免干扰到当前正在运行的服务进程[^5]。 另外一种更为简便的方法是借助图形界面管理程序 Virt-Manager 实现自动化部署流程;亦或是按照官方文档指引采用 XML 描述形式定制专属方案[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值