彻底理解进程与线程:从概念到排查实战

刚接触并发编程那阵子,我也被“进程和线程”这两个词搅得头疼。教科书上写“进程是资源分配的最小单位,线程是CPU调度的最小单位”,每个字都认识,连在一起却像绕口令。后来在真实的项目里排查线上问题、调优接口耗时、设计定时任务框架,才慢慢把这些概念从抽象定义变成了肌肉记忆。这篇文章不讲长篇大论,就用实际开发中能看到的案例、能跑的代码、能用的命令,把进程和线程这层窗户纸捅破,帮你在写代码时知道自己在用什么,出了问题也知道往哪个方向查。

如果你正在学编程、准备面试,或者是写了好几年业务代码但没机会深入系统底层的人,这篇文章应该能给你一个清晰、能落地的认知框架。我会先从生活场景切入,再逐步进入操作系统层面的细节,最后给出一批可以直接上手的实测命令和代码,以及我踩过的坑。整个过程尽量说人话,复杂的地方用类比补上。

1. 先别背定义:用一个后厨场景搞懂两个词的含义

1.1 后厨、灶台、厨师和菜单

想象你开了一家餐厅。整个餐厅有自己独立的店面、厨房设备、库房和菜单,这套完整的经营体系就像一个进程。厨房里的灶台、锅铲、食材,对应着进程拥有的内存、文件句柄和其他资源。但光有餐厅和厨房,菜不会自己跑出来,还得有厨师在里面动手干活。

厨师在同一个厨房里忙活,共用灶台、共用食材、共用调味料,但是每一位厨师手里正在颠勺的动作、此刻脑子里想着“这道菜下一步是放盐还是放醋”的状态,是各自独立的。这些独立动作和当前状态,就是线程的贴身财产。

这个类比能立刻解释几个关键点:

  • 进程是资源的容器,它管着厨房里的所有家当;线程是容器里干活的人,它真正消耗CPU时间。
  • 同一个进程里的多个线程,共享厨房里的公共资源,所以线程之间交流很方便,但也容易因为“抢同一个锅”而产生冲突。
  • 如果餐厅整体倒闭,里面的厨师自然也就失业了;但个别厨师手滑烧了一个灶头,可能整个厨房都要停业整顿,这也是进程与线程在崩溃隔离上的差异。

1.2 从餐厅到操作系统:资源与执行的关系

操作系统里的进程,就是程序的一次运行实例。每启动一个程序,操作系统会给它分配一块独立的虚拟地址空间、一份文件描述符表、一组环境变量和至少一个执行流。这个“执行流”就是主线程。所以严格来说,任何进程都至少有一个线程,线程是进程内部的实际执行者。

“资源分配”和“执行调度”这两件事被拆开,是现代操作系统最重要的设计之一。如果一个进程既持有资源又只能自己单线操作,那当它等待磁盘数据时,整块资源都闲着,CPU也停下来,太浪费。有了线程之后,进程内的多个执行流可以分时使用CPU:一个线程在等I/O,另一个线程可以继续计算,资源始终在转,厨房的师傅们可以交替干活。

这个分工在浏览器里看得特别清楚。现在主流浏览器普遍采用多进程架构,每个标签页可能是一个独立的进程,这样某个标签页崩溃不会把整个浏览器拖垮;而进程内部,渲染、网络请求、用户交互又有多个线程协同工作。你一边看视频一边滚动页面,就是多个线程在背后不停地切换。

2. 深入一点:进程和线程在系统里分别是什么

2.1 进程的“家当”:地址空间、文件表、信号处理器

在Linux里,每个进程都由一个task_struct结构体描述,这个结构体大得惊人,包含进程状态、调度信息、打开的文件、文件系统上下文、信号处理、内存管理等等。我们把进程当作一个独立的“虚拟世界”:

  • 地址空间:每个进程有自己独立的页表,虚拟地址从0到最大地址都只属于自己。A进程在地址0x1000写一个值,B进程即使在同一个地址也不会受影响,因为经过页表映射后,它们落在完全不同的物理页上。
  • 文件表:进程打开的文件、socket、管道,都记录在文件描述符表里。多个线程共享这张表,但两个不同进程之间是完全隔离的,所以要跨进程传数据,就得靠管道、共享内存、socket这类专门的IPC机制。
  • 信号处理器:进程可以对信号(比如SIGINT、SIGTERM)注册统一的处理函数。同一个进程里的线程触发的信号,会由进程的主线程或某个约定线程来处理,这也和线程的私有状态不同。

这些“家当”都是为了隔离。进程是安全边界的执行单位,一个进程不能直接读写另一个进程的内存,这就是为什么多进程程序更稳、更安全,但也更重。

2.2 线程的“私人物品”:栈、寄存器、线程控制块

线程不是完全没有自己的资源。每个线程至少要有:

  • 线程栈:存放函数调用的局部变量、返回地址、参数。线程栈通常从几MB到几十MB(用ulimit -s可以查看),这个大块内存是从进程的虚拟地址空间中分配的,但是每个线程只能用自己的那块区域。
  • 寄存器上下文:程序计数器、栈指针、通用寄存器等。线程切换时,操作系统保存当前线程的寄存器值,恢复下一个线程的寄存器值,这个工作比进程切换轻量。
  • 线程控制块(TCB):记录线程ID、线程状态、调度优先级、栈基址等。

同一进程内的多个线程,共享代码段、数据段、堆、打开的文件描述符和当前工作目录。也就是说,线程A里new出来的对象,线程B可以直接引用它的地址;线程A打开的文件,线程B可以直接读写同一个文件描述符。这既是方便,也是危险的根源。数据竞争、死锁、资源争用,全都诞生在这里。

2.3 线程模型的差异:用户级、内核级与混合模型

线程在不同的操作系统上实现方式不一样。在Linux上,线程本质上是一种“轻量级进程”,创建线程时使用clone系统调用,并且可以传参控制共享哪些资源;但内核会的调度单位是线程,不是进程。在早期的Solaris系统上,出现过用户级线程(用户空间实现,内核并不知道)和内核级线程(内核知道并调度)的区分。

现在主流语言(Java、Go、C++的std::thread)使用的线程,几乎都会对应到内核级线程或者由运行时调度的协程。为什么不用纯用户级线程?因为内核级线程可以享受多核并行,用户级线程在单线程进程里无法利用多核。但用户级线程切换开销极小,所以Go语言另辟蹊径,用协程(goroutine)自己做调度,底层再映射到少量内核线程上,兼顾了并发和性能。

3. 什么时候该上多进程,什么时候该上多线程

3.1 看业务是CPU密集还是I/O密集

这是选型时最重要的判断标准。

如果任务是纯计算,比如视频编码、加密解密、矩阵运算,这类任务几乎不等待外部资源,主要消耗CPU。多线程在单核上不会加速,只能来回切换;在多核上,如果语言和运行时没有特殊的锁竞争限制,多线程可以打满多个核心。但要注意,如果计算任务之间需要频繁同步,性能会被锁拖垮。这种情况下,多进程配合消息传递,有时比多线程更干净。

如果任务是I/O密集,比如读写数据库、调用远程接口、读写文件,大部分时间线程都阻塞在等待结果上。此时用多线程很合适:一个线程等在I/O上,CPU可以去跑另一个线程。Java里动辄上千个线程也没问题,因为大量线程都在阻塞,实际占用CPU的很少。Python因为有GIL,多线程在纯Python的CPU密集任务上基本没有加速效果,但做I/O密集任务时可以用线程池,因为等待I/O时会释放GIL。

3.2 看数据隔离的要求

多进程的核心优势是内存隔离。一个进程崩溃,不会直接把另一个进程的内存搞坏;子进程内存越界,最多把自己所在的地址空间冲掉,父进程通常还能善后并重启。这在需要高可靠的系统里非常重要,比如浏览器、数据库。

但如果业务数据本来就存在一个大对象模型里,多个任务需要频繁修改同一个结构,多线程就更适合。拿电商库存来举例,一个订单扣减库存需要同时修改订单表和库存表,如果拆成不同进程,必须用IPC同步,代码复杂度会直线上升;用线程加锁,直接访问共享内存,写起来更直白。当然,加锁要小心,锁的粒度、顺序都要想清楚,否则死锁就会找上门。

3.3 看团队熟悉的调试方式

这个因素很容易被忽略,但在真实项目里往往是决定性的。多进程程序的问题往往表现为通信错乱、数据不同步,排查时要靠日志把多个进程的时序拼起来,难度很大。多线程程序虽然也有资源竞争和死锁问题,但至少所有线程的堆栈可以在一个进程里用调试器抓出来,许多IDE都能直观展示线程状态。

我的建议是:小团队、快速迭代的内部服务,优先用多线程,因为好排查、好维护;需要稳定性强、模块边界清晰的系统,考虑多进程。两者并不互斥,比如一个后台服务可以由多个进程组成,每个进程内部再用线程池处理请求。

4. 动手验证:用代码感受进程和线程的差异

4.1 Python里的threading和multiprocessing实测

Python是感受进程和线程差异最方便的语言。我们写一个极度消耗CPU的函数,分别用线程池和进程池跑,看时间差别。

import time from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor def calculate(n): s = 0 for i in range(n): s += i * i return s def run_in_thread(workers): with ThreadPoolExecutor(max_workers=workers) as ex: list(ex.map(calculate, [3000000] * workers)) def run_in_process(workers): with ProcessPoolExecutor(max_workers=workers) as ex: list(ex.map(calculate, [3000000] * workers)) if __name__ == '__main__': workers = 4 t0 = time.perf_counter() run_in_thread(workers) print(f"threads: {time.perf_counter() - t0:.2f}s") t0 = time.perf_counter() run_in_process(workers) print(f"processes: {time.perf_counter() - t0:.2f}s")

在我的一台四核虚拟机上,线程版的耗时大约4秒出头,进程版大约1秒出头。原因就是Python的GIL:同一时刻只有一个线程能执行Python字节码。多线程在CPU密集任务上不但没有加速,反而有切换开销。而多进程各自有一个独立的解释器,可以真正跑满多个核心。

这个测试不是劝退线程,而是提醒你:不同语言运行时机制不同,不要拿Java的经验直接套Python。

4.2 Java里用Thread和ProcessBuilder做对比

Java的每个线程都映射到操作系统线程,CPU密集任务可以天然多核并行。先看线程共享变量的效果:

public class ThreadDemo { static int count = 0; public static void main(String[] args) throws Exception { Thread[] threads = new Thread[10]; for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(() -> { for (int j = 0; j < 10000; j++) { count++; } }); threads[i].start(); } for (Thread t : threads) t.join(); System.out.println("count = " + count); } }

这个程序的结果大概率不是100000,因为count++不是一个原子操作,两个线程可能同时读到同一个旧值,加完写回,造成丢失更新。改成AtomicInteger或者加synchronized就能得到正确结果,但这同时引入了同步开销。

再看进程隔离的版本,用ProcessBuilder启动一个子进程。子进程里的变量修改,父进程完全看不见,只能通过输出流拿到结果。这就像两个独立的餐厅,后厨再热闹,隔壁餐厅也听不到。

import java.io.*; public class ProcessDemo { public static void main(String[] args) throws Exception { Process p = new ProcessBuilder("java", "-version") .redirectErrorStream(true) .start(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } System.out.println("exit code = " + p.waitFor()); } }

4.3 用系统命令查看进程和线程

纸上得来终觉浅,直接在系统里看更直观。

  • ps -eLf:每一行代表一个进程里的一个线程,LWP就是线程ID。你可以看到同一个PID下有多条LWP记录。
  • top -H -p <pid>:按线程维度展示CPU占用,可以快速发现哪个线程在疯狂消费CPU。
  • cat /proc/<pid>/status | grep Threads:直接看到这个进程当前有多少个线程。
  • Java程序可以用jstack <pid>打印出所有线程的堆栈,排查死锁时几乎必用。

上次排查一个接口卡死问题,我先用top -H -p看到某个线程CPU持续100%,再用jstack抓到线程栈,发现是在一个正则匹配的死循环里。如果没有线程维度的观察命令,根本不可能在杂乱的服务里定位到这么细。

5. 真正干活时才会踩的坑和排查思路

5.1 线程死锁:怎么发现和避免

死锁的经典场景是线程A持有锁1,等待锁2;线程B持有锁2,等待锁1。一旦形成循环等待,两个线程就永久卡住。线上表现通常是某个接口不再返回,但是线程还在。

排查方法:

  • Java环境先用jstack抓线程转储,里面会明确提示Found one Java-level deadlock,并列出线程各自持有的锁和等待的锁。
  • Python环境可以分别访问线程的信号?实际上Python没有内置死锁检测,但可以每隔一段时间把当前线程栈打印出来,或者用faulthandler.dump_traceback_later(10)。
  • 预防死锁最简单的方法是给锁排序:所有线程都按固定顺序获取多个锁,不要交叉使用。比如先锁A再锁B,永远不要先锁B再锁A。

5.2 进程通信要选对IPC:管道、共享内存、消息队列

多进程之间没有共享内存,所以必须用IPC。管道适合父子进程之间单向传递简单数据,用起来最简单;共享内存适合传递大量数据,性能最好,但需要自己处理同步和生命周期;消息队列和socket则适合跨机器、跨语言的场景。

我见过一个系统,为了追求性能,用了共享内存,却忘了在共享内存里加锁。结果两个进程同时写一个槽位,数据一会儿对一会儿错,非常难排查。后来改成环形缓冲区加自旋锁,才稳定下来。IPC没有银弹,选型时要把数据量、实时性、开发成本排个优先级,而不是只看性能。

5.3 线程池的线程数到底设多少

这个问题几乎每个项目都会遇到。一个经验公式:

  • 计算密集型任务:线程数约等于CPU核心数(或者核心数+1,留一点余地)。
  • I/O密集型任务:线程数可以设到核心数的几倍甚至几十倍,因为大部分线程在等待I/O,不占CPU时间。
  • 更准确的方法是压测,观察线程池队列增长、CPU利用率和响应时间,再动态调整。

很多框架都有动态线程池的配置,比如Java的ThreadPoolExecutor允许核心线程数和最大线程数调整,不要把参数写死成永远不变的值。我见过有人把线程池最大线程数设成10000,结果每个线程默认占用1MB栈,光栈内存就吃了10GB,服务刚上线就OOM。

5.4 崩溃隔离:进程挂了线程还在吗

这是一个常见的误解。进程是资源容器,线程是容器内的执行流。进程一旦退出,内核会回收该进程的所有资源,包括它的所有线程。所以“主线程结束了,子线程还能不能继续跑”这个问题的答案是:取决于你怎么结束。

在C/C++里,从main函数返回会调用exit,所有线程立即终止;但如果你调用pthread_exit只退出当前线程,其他线程可以继续。在Java里,当所有非守护线程都结束时,JVM才会退出;守护线程会自动终止。Python里主线程结束,非守护子线程通常也会被强制结束。所以设计生命周期时,一定要明确线程的退出时机,否则可能出现任务还没跑完,进程就已经散场的情况。

6. 从调度视角再往后看一眼

6.1 操作系统到底在调度什么

现代Linux内核调度的基本实体是线程。内核看到的是一个个task,每个task有独立的上下文和调度策略。所以当你创建一个进程时,实际就是创建了一个包含主线程的task;在这个进程里再创建线程,就是增加共享同一地址空间的新task。

这种设计让线程切换只涉及寄存器上下文切换,而进程切换需要处理地址空间切换(换页表、刷新TLB)。同一个进程内线程切换成本远低于进程切换,这就是为什么线程被称为“轻量级进程”。但这个“轻量”是相对的:线程创建和销毁也需要内核调用,频繁创建销毁线程同样会让系统性能受损,所以线程池和进程池都是减少这种开销的常用手段。

6.2 协程和线程的关系:并发不一定是并行

把线程往更轻的方向推一步,就出现了协程。协程是用户态的调度单元,它没有独立的内核栈,切换时只需要保存少量寄存器,所以切换成本比线程低一个数量级。但协程一般是协作式调度,一个协程阻塞了,如果没有特殊机制,整个线程就卡住了。

在实际工程里,很多语言已经把协程包装得很完善。Go的goroutine会在某个协程发起阻塞I/O时,自动把该线程让给其他协程;Java的虚拟线程也走类似路线。理解协程之前,先理解线程是很有必要的,因为协程最终还是跑在线程上,操作系统的调度依然以线程为单位。

个人体会

我在实际项目中见过太多因为没分清进程和线程而导致的故障:有把进程通信写成共享内存导致数据错乱的,有为了并发把线程池线程数调到离谱结果的,也有在线程里直接修改全局变量导致线上偶发问题的。这些问题的根源,往往不是因为不懂API,而是没建立“资源归属”和“执行流”分离的思维模型。

每次写并发代码之前,我都会先问自己:这里的数据需要共享吗?如果不需要,优先拆进程;如果需要共享,再想清楚同步方式。这个习惯帮我省下了大量排查时间。理解进程和线程不是背概念,而是在自己的代码里画一条清晰的边界:什么资源属于整个容器,什么状态只属于当前这条执行流。边界画清楚了,并发编程就成功了一大半。

相关新闻

SLAM技术工程化实践:激光与视觉惯性里程计复现与调参指南

SLAM技术工程化实践:激光与视觉惯性里程计复现与调参指南

简介&#xff1a;本资源为高博《自动驾驶与机器人中的SLAM技术》源码修改版&#xff0c;面向自动驾驶、机器人及SLAM方向的开发者与深蓝学院学员&#xff0c;提供经定制调整的可运行代码&#xff0c;帮助读者从传感器数据、建图算法到优化模块直观理解完整实现流程。压缩包约23…

2026/10/20 17:09:34 阅读更多 →
机器学习与深度学习:区别、原理与实战指南

机器学习与深度学习:区别、原理与实战指南

机器学习、深度学习这两个词&#xff0c;这几年几乎已经被说烂了。但真被问到“区别到底是什么、我该先学哪个、实际项目里怎么用”&#xff0c;能一句话讲清楚的人并不多。作为常年跟数据打交道的人&#xff0c;我习惯把机器学习理解成“按菜谱学做菜”&#xff1a;你告诉系统…

2026/10/20 17:09:34 阅读更多 →
accountaccessor.dll报错怎么办?免费安全的系统修复方法

accountaccessor.dll报错怎么办?免费安全的系统修复方法

先说实话&#xff1a;accountaccessor.dll 这种系统组件报错&#xff0c;80% 以上的“免费下载”方案&#xff0c;反而是把电脑推向更坑的深渊。我在日常帮人修电脑的过程里&#xff0c;隔三差五就能遇到这类问题。很多人第一反应就是打开搜索&#xff0c;找到一堆“dll下载站”…

2026/10/20 17:09:34 阅读更多 →

最新新闻

Qt课程进度导航栏G03:从数据模型到自绘渲染的完整实践

Qt课程进度导航栏G03:从数据模型到自绘渲染的完整实践

做教育类桌面客户端的时候&#xff0c;课程导航一直是个绕不开的活儿。用户要在一个窗口里看到章、节、课时的层级关系&#xff0c;要清楚自己学到哪了&#xff0c;还得能一键跳回上次退出的位置。市面上的现成组件大多只解决“展示目录”这一层&#xff0c;进度状态、学习记忆…

2026/10/20 17:53:47 阅读更多 →
软件设计师上午题解题切片:真题陷阱、能力断点与命题逻辑拆解

软件设计师上午题解题切片:真题陷阱、能力断点与命题逻辑拆解

简介&#xff1a;本资源为2025年下半年全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试——软件设计师科目上午卷的真题解析与标准答案全集&#xff0c;专为备考该认证的计算机专业技术人员设计&#xff0c;聚焦基础知识巩固、解题逻辑训练与应试策略提升。…

2026/10/20 17:53:47 阅读更多 →
卫星姿态轨道控制Simulink仿真实践:从翻滚到对地定向的完整闭环

卫星姿态轨道控制Simulink仿真实践:从翻滚到对地定向的完整闭环

想真正弄明白卫星姿态轨道控制&#xff0c;光看资料是不够的。我见过不少人手里攒着好几份讲义和开源工程&#xff0c;每个模块单独看都能讲出头头是道&#xff0c;但要自己在Simulink里搭一条“从翻滚状态到对地定向稳定”的完整闭环&#xff0c;就卡住了。这篇博文就是一次卫…

2026/10/20 17:53:47 阅读更多 →
Microsoft Agent Framework迁移指南:从Semantic Kernel到自治AI代理

Microsoft Agent Framework迁移指南:从Semantic Kernel到自治AI代理

1. 项目概述&#xff1a;这不是一次简单的工具替换&#xff0c;而是一场底层思维的迁移“.NET AI 生态系统的重构与演进&#xff1a;Microsoft Agent Framework 对 Semantic Kernel 的继承、超越与战略整合”——这个标题里藏着一个被很多人忽略的关键事实&#xff1a;它不是在…

2026/10/20 17:53:47 阅读更多 →
每瓦Token成AI工厂新KPI,NVIDIA全栈升级如何提升能效

每瓦Token成AI工厂新KPI,NVIDIA全栈升级如何提升能效

AI算力圈最近都在聊一个新词&#xff1a;每瓦Token。这玩意儿不是厂商营销造出来的概念&#xff0c;而是实实在在成了衡量AI数据中心“生产效率”的硬指标。过去大家比的是峰值算力&#xff0c;也就是FP16、FP8下的TOPS数值&#xff0c;现在风向明显变了&#xff0c;大家开始盯…

2026/10/20 17:53:47 阅读更多 →
JMeter接口测试进阶:从参数化、断言到结果分析的核心能力

JMeter接口测试进阶:从参数化、断言到结果分析的核心能力

做接口测试这行&#xff0c;接触JMeter是早晚的事。早年我还在手工点接口文档、拿浏览器调试工具一个个试请求的时候&#xff0c;第一次用JMeter跑通一个几十线程的并发场景&#xff0c;那感觉确实挺新鲜。但说句实在话&#xff0c;从“会用JMeter”到“能把接口测试做出价值”…

2026/10/20 17:52:45 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →