Linux进程CPU绑定优化与实践过程

2025-07-13 18:50

本文主要是介绍Linux进程CPU绑定优化与实践过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适...

简介:Linux操作系统支持将进程绑定到特定的CPU核心,以提升性能和负载平衡。

本主题涵盖多核处理器、CPU亲和性设置、系统调用 sched_setaffinity sched_getaffinity 的使用,以及 taskset 命令行工具的实际操作。

通过 cpu_test.cpp 示例,学习如何在C++中控制CPU绑定,并探讨在性能优化、负载均衡和避免干扰方面的应用场景。

Linux进程CPU绑定优化与实践过程

1. 多核处理器及并行计算概念

在现代计算机系统中,多核处理器已成为标准配置,为并行计算提供了强大的物理基础。

理解多核处理器的工作原理及其在并行计算中的角色对于IT专业人员来说至关重要。

本章节将从基础开始,逐步深入,介绍多核处理器的架构,以及并行计算的基本概念。

1.1 多核处理器架构概述

多核处理器由两个或更多独立的处理器核心组成,这些核心共享缓存和其他资源,但能在同一芯片上独立执行计算任务。

与单核处理器相比,多核处理器能在相同功耗下提供更高的处理能力。

1.2 并行计算的含义及重要性

并行计算是指同时使用多个计算资源解决计算问题的过程。

在多核处理器上实现并行计算,能够显著提高数据处理速度和算法效率。

这对于处理大数据集和执行复杂计算任务尤为重要。

1.3 并行计算模型和策略

并行计算模型描述了并行算法的设计和执行策略。它包括任务分解、任务分配、任务调度和结果收集等关键步骤。理解不同的并行计算模型,如共享内存模型和分布式内存模型,对于设计高效的并行程序至关重要。

在下一章,我们将详细介绍CPU亲和性的基本概念,它是并行计算中的一个重要技术,用于改善进程调度,提高系统性能。

2. CPU亲和性(CPU Affinity)概念及应用

2.1 CPU亲和性的基本概念

2.1.1 CPU亲和性的定义与重要性

CPU亲和性是操作系统中用于控制进程或线程与特定CPU核心绑定的功能,以保证执行的连续性和数据的本地性,从而优化性能。它允许系统管理员和程序员决定哪些进程或线程应在特定的CPU核心上运行,或者不应在哪些核心上运行。

为什么CPU亲和性重要呢?其原因包括:

  • 缓存利用效率: CPU缓存用于存储临时数据,如果进程在不同的CPU核心间频繁切换,缓存利用效率会降低,因为每个核心的缓存内容不同。通过亲和性,可以使得进程更频繁地在同一个核心上运行,从而充分利用缓存。
  • 减少上下文切换开销: 上下文切换涉及保存当前进程状态和加载另一个进程状态,此操作耗时且资源密集。通过限制进程只能在指定核心上运行,可以减少不必要的上下文切换。
  • 提升实时性能: 在实时操作系统中,需要确保关键任务能够及时响应。CPU亲和性可以帮助确保关键进程获得必要的CPU时间片,从而保证实时性。

2.1.2 CPU亲和性的技术原理

技术原理围绕进程调度与CPU核心间的关系展开。当操作系统调度一个进程执行时,若该进程绑定了特定的CPU核心,那么调度器会将进程投递到指定的核心上执行。相反,如果没有进行绑定,则调度器可以将进程分配到任意一个空闲的CPU核心上。

实现CPU亲和性通常涉及以下步骤:

  1. 进程识别: 首先,操作系统需要识别出需要进行CPU亲和性设置的进程或线程。
  2. 绑定指令: 调度器使用特定的内核函数或系统调用将进程与CPU核心进行绑定。例如,在Linux中,可以使用 sched_setaffinity 系统调用。
  3. 调度决策: 在进行调度决策时,调度器会考虑到进程的亲和性设置,尽量避免违反绑定的约束。

CPU亲和性的实现技术对于系统性能有着直接的影响,因此在多核处理器广泛使用的当下,成为系统调优的关键技术之一。

2.2sched_setaffinity系统调用应用

2.2.1sched_setaffinity的定义与作用

sched_setaffinity 是一个在类Unix操作系统中实现的系统调用,用于设置进程的CPU亲和性掩码。

其作用是限制一个或多个进程只能在一组特定的CPU核心上运行,从而进行性能调优或满足特定的资源分配需求。

2.2.2sched_setaffinity使用方法详解

要使用 sched_setaffinity ,你需要提供以下几个参数:

  • pid :进程ID,表示要修改亲和性的进程标识符。
  • cpusetsize :CPU集大小,表示接China编程下来传入的cpumask长度。
  • cpumask :CPU掩码,是一个位掩码,指明了哪些CPU核心是允许进程运行的。

一个典型的使用示例代码如下:

#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

#define CPU_SETSIZE 4 /* 最大支持4个CPU */
#define NCPUS 4 /* CPU个数 */

int main(int argc, char *argv[]) {
    cpu_set_t mask;
    int i, ret, n;
    // 清空mask
    CPU_ZERO(&mask);

    // 将第2个和第4个CPU加入到mask中(数组索引从0开始计数)
    CPU_SET(1, &mask); // 使进程只能运行在CPU 1上
    CPU_SET(3, &mask); // 使进程只能运行在CPU 3上

    n =syscall(SYS_sched_setaffinity, 0, sizeof(mask), &mask);
    if (n == -1) {
        perror("sched_setaffinity");
        exit(EXIT_FAILURE);
    }

    // 检查实际的CPU亲和性掩码
    ret = syscall(SYS_sched_getaffinity, 0, sizeof(mask), &mask);
    if (ret == -1) {
        perror("sched_getaffinity");
        exit(EXIT_FAILURE);
    }

    printf("CPU affinity mask is %08x %08x\n", mask.__bits[0], mask.__bipythonts[1]);
    return 0;
}

在上述示例中,首先创建了一个cpu_set_t类型的变量mask,然后使用 CPU_SET 宏设置进程能运行的CPU核心。

调用 syscall 函数执行 sched_setaffinity 系统调用,并用 sched_getaffinity 查询以确认设置是否成功。

2.2.3 使用sched_setaffinity进行进程CPU绑定案例分析

假设有一个计算密集型的应用程序,它对性能有很高的要求。通过使用 sched_setaffinity ,我们可以指定该应用程序的进程只在特定的CPU核心上运行,这样可以减少缓存未命中的情况,同时避免了不必要的上下文切换。

在这个案例中,假设系统有4个CPU核心,我们将进程绑定在第1个和第3个核心上运行。下面是具体的步骤:

  1. 初始化CPU掩码,并设置需要绑定的CPU核心。
  2. 调用 sched_setaffinity 设置进程的亲和性。
  3. 运行该进程并观察性能改善情况。
  4. 使用 sched_getaffinity 确认绑定设置是否生效。

通过性能监控工具(如 top htop perf )观察进程的CPU使用情况,可以看到该进程只在指定的核心上运行,而没有分散到其他核心。

2.3sched_getaffinity系统调用应用

2.3.1sched_getaffinity的定义与作用

sched_getaffinity 是一个系统调用,用于获取进程的CPU亲和性掩码。

它的作用是返回一个位掩码,表示进程可以在哪些CPU核心上运行,有助于管理员或开发者检查和验证进程的CPU绑定情况。

2.3.2sched_getaffinity使用方法详解

使用 sched_getaffinity 需要以下参数:

  • pid :进程ID,需要查询亲和性的进程标识符。
  • cpusetsize :与 sched_setaffinity 中相同,表示cpumask的大小。
  • cpumask :用于存储返回的CPU亲和性掩码。

示例代码如下:

#include <sched.h>
#include <pythonstdio.h>
#include <unistd.h>

#define CPU_SETSIZE 4 /* 最大支持4个CPU */

int main(int argc, char *argv[]) {
    cpu_set_t mask;
    int i, n;
    // 清空mask
    CPU_ZERO(&mask);
    // 获取进程的CPU亲和性掩码
    n = sched_getaffinity(0, sizeof(mask), &mask);
    if (n == -1) {
        perror("sched_getaffinity");
        exit(EXIT_FAILURE);
    }

    printf("CPU affinity mask is %08x %08x\n", mask.__bits[0], mask.__bits[1]);
    for (i = 0; i < CPU_SETSIZE; i++) {
        if (CPU_ISSET(i, &mask)) {
            printf("Process can run on CPU %d\n", i);
        } else {
            printf("Process cannot run on CPU %d\n", i);
        }
    }
    return 0;
}

代码首先定义了一个cpu_set_t类型的变量mask,然后使用 CPU_ZERO 宏清空该掩码。

接着调用 sched_getaffinity 获取当前进程的CPU亲和性掩码,并通过循环打印出可以运行的CPU核心。

2.3.3 使用sched_getaffinity查看进程CPU亲和性的案例分析

假设我们有一个运行中的多线程服务器应用,我们需要确认其工作线程是否正确地绑定到了预期的CPU核心上。

在这种情况下,我们可以使用 sched_getaffinity 来获取并检查每个工作线程的CPU亲和性掩码。

具体步骤如下:

  1. 对于每个工作线程,调用 sched_getaffinity 来获取它的CPU亲和性掩码。
  2. 打印并检查掩码,确认每个工作线程是否仅绑定到了预期的CPU核心。
  3. 如果有线程的亲和性掩码不正确,可以通过 sched_setaffinity 调整它们。

通过这种检查,可以确保线程负载在CPU核心间得到适当的分配,并避免不必要的线程移动导致性能下降。

3.taskset工具使用及实例

3.1taskset工具概述

taskset 是Linux系统中的一个命令行工具,允许用户显示或设置一个进程的CPU亲和性。CPU亲和性是指进程或线程在特定的CPU上运行的趋势,它有助于减少进程在不同CPU之间的迁移,从而提高系统性能。

3.1.1taskset的功能与应用场景

taskset 常用于以下场景:

  • 系统优化 :当需要确保关键进程总是在特定的CPU核心上运行,以最小化上下文切换开销。
  • 任务隔离 :为特定进程分配固定的CPU资源,以避免和其它进程的资源竞争。
  • 实时性能保证 :在实时系统中,保证某些实时进程不会因为CPU调度问题而延迟执行。

taskset 的主要作用是让进程或线程在指定的CPU核心上运行,这在多核处理器系统中尤为有用。它通过设置进程的CPU掩码(CPU mask)来实现,CPU掩码是一个位掩码,指明了进程可以在哪些CPU核心上运行。

3.1.2taskset命令的基本语法

taskset 命令的基本用法如下:

taskset [OPTIONS] [MASK] [COMMAND] [ARGS]
编程China编程
  • MASK :可以是十六进制或十进制格式的CPU掩码,用于指定进程可以运行的CPU核心。
  • COMMAND :需要设置CPU亲和性的命令。
  • ARGS :传递给 COMMAND 的参数。
  • [OPTIONS] :可选参数,例如 -p ,可以在不重启进程的情况下动态改变现有进程的CPU亲和性。

接下来,我们深入探讨使用 taskset 工具的具体实例。

3.2taskset使用实例

3.2.1 使用taskset修改进程CPU亲和性实例

假设我们有一个计算密集型的程序 myapp ,我们希望它只在一个核心上运行。

可以使用如下命令来实现:

taskset -c 1 ./myapp

这里 -c 1 表示设置CPU亲和性掩码为 0000 0010 (二进制表示),即只允许进程运行在第二个核心上(核心编号从0开始)。如果系统是多核的,更改数字可以指定不同的核心。

3.2.2 使用taskset绑定进程至特定CPU的实践操作

更复杂的例子是同时指定多个核心。假设我们希望程序 myapp 可以运行在CPU 1和CPU 3上,可以使用如下命令:

taskset -c 2,6 ./myapp

这里 -c 2,6 表示设置CPU掩码为 0100 0100 (二进制表示),即程序 myapp 可以运行在第二个和第四个核心上(分别编号为1和3,因为从0开始计数)。

为了验证 taskset 命令是否正确工作,可以使用以下命令来查看进程的CPU亲和性:

taskset -p <pid>

其中 <pid> 是进程的ID。该命令会输出当前的CPU亲和性掩码。

以下是 taskset 命令在实际工作中的一个表格示例,详细展示不同选项和参数的使用场景:

| 命令选项 | 描述 | 示例 | |-------|-----|-----| | -c | 为进程指定CPU亲和性掩码 | taskset -c 0,2-3 myapp 将myapp绑定到CPU 0,2,3 | | -p | 针对已有进程的CPU亲和性设置 | taskset -p 0x01 myapp 修改myapp进程的CPU亲和性 | | -V | 显示版本信息 | taskset -V 显示taskset的版本信息 |

在接下来的章节中,我们将深入探讨 cpu_test.cpp 示例程序的详细分析,以及多核CPU绑定在不同应用场景中的优化策略和最佳实践。

4. Linux下进程绑定多CPU运行的代码实践

4.1cpu_test.cpp示例程序探讨

4.1.1 程序设计思路分析

在探讨 cpu_test.cpp 示例程序之前,我们首先需要理解该程序的设计意图与执行逻辑。该程序的主要目的是为了演示如何在Linux环境下,通过代码实现将特定的进程绑定至一个或多个CPU核心上运行。为了达到这个目的,程序需要完成以下几个核心步骤:

  1. 获取CPU核心信息: 程序通过读取系统文件或利用系统API来获取CPU的核心信息,这包括CPU的总数量以及每个核心的逻辑标识符。
  2. 进程创建: 程序需要创建或指定一个进程,这个进程将被用于后续的CPU绑定操作。
  3. CPU亲和性设置: 使用Linux提供的系统调用或API,如 sched_setaffinity ,来设置进程的CPU亲和性,使进程只在特定的CPU核心上运行。
  4. 运行测试: 进行一系列测试,以验证设置是否成功,并观察进程在绑定CPU核心后的行为和性能表现。

4.1.2cpu_test.cpp代码结构与功能解读

接下来,我们逐步深入到 cpu_test.cpp 的代码结构中去,了解其功能实现:

#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/sysinfo.h>

int main(int argc, char *argv[]) {
    // 获取CPU核心数量
    int num_cpus = get_nprocs();
    cpu_set_t cpuset;
    // 初始化CPU集合为空
    CPU_ZERO(&cpuset);
    // 绑定进程至第一个CPU
    CPU_SET(0, &cpuset);
    // 设置进程CPU亲和性
    if (sched_setaffinity(0, sizeof(cpuset), &cpuset) == -1) {
        perror("sched_setaffinity");
        exit(EXIT_FAILURE);
    }
    // 进程执行代码
    // ...

    return 0;
}

上述代码主要完成以下几个任务:

  • 获取CPU核心数量 get_nprocs 函数用于获取当前系统中可用的CPU核心数量。
  • 初始化CPU集合 CPU_ZERO 用于初始化一个 cpu_set_t 类型的数据结构,该结构用于表示CPU的集合。通过该操作,我们将这个集合清空,为后续添加CPU核心做准备。
  • 设置CPU亲和性 sched_setaffinity 函数用于设置当前进程的CPU亲和性。该函数的参数包括进程标识符、CPU集合的大小以及CPU集合本身。在这个例子中,我们将进程绑定到第一个CPU核心(CPU 0)。php
  • 执行业务代码 :在设置了CPU亲和性之后,业务代码将被执行,但在此处代码中为了简洁,具体的业务代码部分被省略。

4.1.3cpu_test.cpp测试结果与分析

为了验证上述程序的效果,需要对程序运行结果进行分析。测试通常包括以下几个步骤:

  1. 编译并运行程序 :首先确保程序编译无误后,运行该程序。
  2. 检查进程运行情况 :使用 top htop 命令检查进程是否真的运行在指定的CPU核心上。
  3. 性能测试 :可使用 perf 等性能分析工具,观察绑定后进程的性能表现是否有所提升。

测试结果表明,当 cpu_test.cpp 被正确编译并运行后,指定的进程将会被锁定在设定的CPU核心上运行。这种绑定可以显著提高多核心处理器上并行计算任务的效率。

4.2 CPU绑定应用场景分析

在现代的计算机系统中,CPU绑定技术可以被应用在多种场景下以优化性能。以下是几个具体的应用场景:

4.2.1 多CPU绑定在高性能计算中的应用

在高性能计算领域,科学计算任务往往需要大量的计算资源。通过将计算任务绑定到多个CPU核心上,可以显著提高并行计算的效率。例如,在进行大规模数值模拟时,各计算节点可以独立并行地处理各自的数据集,从而加快整体计算速度。

4.2.2 多CPU绑定在实时系统中的应用

实时系统对任务的执行时间有严格的要求。通过CPU绑定技术,可以确保实时任务在特定的CPU核心上运行,以避免任务切换带来的延迟,确保任务在规定的时间内完成。

4.2.3 多CPU绑定在服务器负载均衡中的应用

在服务器中,负载均衡是一个关键的性能优化手段。通过合理地将服务器上的进程绑定到不同的CPU核心上,可以避免某些CPU核心过载,而其他核心空闲的情况,从而提高服务器的总体处理能力。

通过以上各部分的分析,我们可以看到在Linux环境下,通过代码实践将进程绑定到特定的CPU核心上运行,是提升系统性能的重要手段。理解并掌握 cpu_test.cpp 示例程序的开发思路与方法,对于从事并行计算、实时系统开发或服务器优化的IT专业人士而言,具有重要的参考价值。

5. 综合优化策略与最佳实践

5.1 综合优化策略

5.1.1 进程调度与CPU亲和性优化

优化CPU亲和性可以提高多核处理器上进程的性能。进程调度器在多核环境中决定进程运行于哪个CPU核心。通过合理分配,可以减少缓存未命中(cache misses)、提高缓存利用率和降低进程间竞争。在Linux中, taskset 命令和 sched_setaffinity 系统调用就是实现CPU亲和性的工具。

在实际应用中,可以通过调整进程调度优先级和CPU亲和性来优化系统性能。例如,对于对实时性要求高的进程,可以设置较高的优先级,并将其绑定到一个或多个核心上运行。而对于计算密集型任务,可以利用亲和性避免进程频繁迁移,减少上下文切换的开销。

5.1.2 系统资源分配与管理策略

系统资源的合理分配对于优化多核处理器系统的性能至关重要。需要考虑的资源包括CPU时间、内存带宽、I/O吞吐量等。合理的资源管理策略能够保证关键任务获得足够的资源,同时避免资源浪费。

资源管理可以分为静态和动态两种。静态管理是根据预期的负载和任务特性在系统启动时预分配资源;动态管理则是在系统运行时根据实际需求实时调整资源分配。Linux提供了诸如cgroups、cpuset等工具来实现资源的动态管理。

5.2 多核CPU绑定的最佳实践

5.2.1 性能测试与调优步骤

进行性能测试和调优时,首先要确立性能指标,如响应时间、吞吐量等。然后,选择合适的工具来监控和记录关键性能指标。常见的性能测试工具包括 perf htop mpstat

测试过程中,可以逐步调整CPU亲和性设置,观察不同配置下性能的变化。这个过程可以使用循环或自动化脚本,快速收集不同配置下的性能数据。数据分析后,选择最优的CPU亲和性配置。

5.2.2 实际部署与运维考量

在实际部署时,应考虑到应用的运行特性以及系统的实时负载情况。根据这些信息,选择合适的时间窗口进行维护和调整,以降低对用户的影响。运维团队应该定期检查性能指标,确保系统的稳定性。

部署阶段,运维人员需要密切监控系统日志和性能指标,及时发现并解决可能的问题。同时,也需要考虑系统的扩展性,为未来的升级和维护留出空间。

5.2.3 常见问题的诊断与解决

在多核CPU系统中,可能会遇到一些性能问题,如资源竞争、死锁或CPU使用不平衡等。当遇到性能瓶颈时,应先确定瓶颈是由CPU亲和性问题还是其他因素导致的。

诊断问题通常需要收集系统运行时的数据,使用工具如 perf 来记录硬件性能计数器信息,并通过分析这些信息找到问题的根源。对于资源竞争问题,可以尝试调整进程的CPU亲和性设置,或者使用cgroups来限制某些进程的资源使用。

对于CPU使用不平衡的问题,需要检查系统的负载分配策略和调度器配置。必要时,可以通过调整调度策略或者重新设计应用架构来解决。

总结

本章到此为止,我们探讨了优化CPU亲和性以及最佳实践的方法。但是需要注意,这些策略需要根据具体情况进行调整。接下来的内容将涉及深入讨论,我们将会探索更多关于多核处理器及并行计算的高级话题。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于Linux进程CPU绑定优化与实践过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155373

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

linux解压缩 xxx.jar文件进行内部操作过程

《linux解压缩xxx.jar文件进行内部操作过程》:本文主要介绍linux解压缩xxx.jar文件进行内部操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、解压文件二、压缩文件总结一、解压文件1、把 xxx.jar 文件放在服务器上,并进入当前目录#

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab