Linux进程间通信:System V消息队列与信号量实战详解
做Linux下多进程开发绕不开的一个话题就是进程间通信。之前我维护过一个嵌入式网关项目四个进程各管一摊活既要互相传数据又要抢着用同一个串口资源最后靠的就是System V IPC里的消息队列和信号量。这篇内容我就把这两个东西讲透它们到底解决什么问题、API怎么用、实际项目里有哪些坑以及面试里经常被问到的点。不管你是写嵌入式Linux应用、做后台服务还是在准备Linux面试这篇应该都能帮上忙。1. 项目概述与方案选型为什么是System V IPC1.1 真实场景什么时候你才需要消息队列和信号量先看一个具体场景。假设你手头有一个采集程序每秒钟从传感器读一批数据另一个程序负责把这些数据压缩后落盘还有一个程序要做心跳上报。三者之间速度不匹配数据流向固定。这时候你也能用匿名管道凑合但管道是字节流没有边界你得在应用层自己定义帧格式、处理粘包而且管道只能单向两个方向要建两条代码很快就乱了。消息队列解决的正是这类问题消息有类型、有边界内核帮你排队发送方和接收方不需要同时在运行——发送方把消息扔进队列就能干别的接收方有空再取。这种解耦能力在生产者-消费者模型里特别舒服。信号量则是另一类问题。比如多个进程要访问同一个硬件寄存器、同一个日志文件或者同一块共享内存。大家都想写谁先谁后信号量就是一把“通行证计数器”拿到通行证才能进入临界区用完归还。它不管数据怎么传输只管“能不能进”。简单说消息队列负责“数据从一个进程到另一个进程”信号量负责“多个进程对共享资源的互斥与同步”。两者组合使用正好覆盖了进程间通信里最常见的数据交换和资源竞争两大类需求。1.2 System V 与 POSIX IPC 的选型对比我见过不少人一上来就纠结到底用System V还是POSIX IPC说实话刚工作那几年我也踩过这个坑——在Linux上写了一个基于POSIX消息队列的组件中间换了一台国产服务器发现某些内核版本上行为不一致折腾了很久才换回System V。两者都能实现消息队列和信号量但区别不小标识方式不同。System V IPC用key_t整型键标识对象POSIX IPC用字符串名字标识可读性上POSIX更好。管理工具不同。System V IPC通过ipcs命令可以直观看到系统里所有信号量、消息队列和共享内存排查问题非常方便POSIX也有对应的lsmq之类的工具但Linux上不是默认自带用起来不如ipcs顺手。功能细节不同。POSIX消息队列支持mq_notify异步通知和超时接收功能更现代System V消息队列没有通知机制只能阻塞或非阻塞轮询。历史兼容性不同。System V IPC出现得早接口更繁琐但胜在稳定、历史包袱少。嵌入式Linux、老一点的服务运维体系里大量代码和脚本都是基于System V的。所以我的选型建议很直白如果你的项目运行在Linux/Unix体系、依赖传统运维工具ipcs/ipcrm或者需要和旧代码兼容直接用System V如果是新写的纯Linux项目、追求异步通知和超时控制可以考虑POSIX。但今天我们的主题是System V因为它在生产环境里覆盖面更广面试也最爱考。1.3 消息队列和信号量的分工还是拿网关项目举例。采集进程把数据封装成消息通过msgget创建的队列发给压缩进程——这是消息队列的活四个进程共享一个串口设备每次只能有一个进程打开串口发指令于是用一个信号量做互斥谁拿到资源谁操作——这是信号量的活。简单总结成一张表对比维度消息队列信号量解决什么问题进程间传递有结构的数据控制共享资源的并发访问数据方向单向或双向均可按类型分发不传数据只传“许可”阻塞行为队列满/空时阻塞或非阻塞资源为零时阻塞等待典型场景生产者-消费者、事件通知互斥锁、资源计数、读写同步排查命令ipcs -qipcs -s这张表是我自己实践下来整理的后面所有代码和分析都围绕这两行展开。2. 消息队列原理、API 与可运行示例2.1 消息队列的工作模型System V消息队列在内核里维护一个队列链表。每个消息由两部分组成一个长整型消息类型mtype一段最大长度受限制的正文mtext。发送方用msgsnd把消息挂到队列尾部接收方用msgrcv按类型取走消息。注意队列不是简单的先进先出而是“按类型择先”——虽然消息在物理上排在队尾但接收方指定类型后内核会从队头开始扫描找到第一个匹配类型的消息把它从队列里摘除并拷贝给调用者。同一类型下的多条消息按时间顺序排列。这个模型有一个特别实用的能力多个接收进程同时等待内核保证一条消息只会被一个进程取走不会出现两份拷贝。这在多个消费者场景里是天然的去重保证。不过要注意取走后消息就从队列里删除了如果接收进程拿到消息还没处理完就崩溃这条消息就丢了。后面讲“消息重复消费问题”时会再提到这一点。2.2 四个核心API逐个拆解创建或获取队列用msgget原型是int msgget(key_t key, int msgflg);key是对象标识。可以用ftok()生成也可以直接用IPC_PRIVATE(0)让内核分配一个唯一标识。IPC_PRIVATE创建的队列只能通过返回值传给子进程适合父子进程场景。msgflg常见组合是IPC_CREAT|0666表示不存在就创建权限为0666。若同时加IPC_EXCL在对象已存在时会返回EEXIST类似open的O_EXCL。发送消息用msgsndint msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msgp指向的结构体必须以long mtype开头后面跟着正文。msgsz是正文的字节数不包括mtype本身。msgflg可以传0阻塞或IPC_NOWAIT非阻塞。队列满了还继续发阻塞时调用线程会挂起非阻塞则返回-1errno为EAGAIN。接收消息用msgrcvssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);msgtyp的语义很灵活等于0取队首第一条消息不管类型。大于0取类型等于msgtyp的第一条消息。小于0取类型小于等于msgtyp绝对值的最小类型消息。比如msgtyp-10表示从所有类型≤10的消息里先挑类型最小的那条。这个设计用于优先级处理给不同任务分配不同类型号数字越小优先级越高。msgctl是控制接口int msgctl(int msqid, int cmd, struct msqid_ds *buf);最常用的是IPC_RMID删除队列其次是IPC_STAT获取属性。删除队列要小心所有阻塞在msgrcv上的进程会立刻返回errno是EIDRM这个问题后面排查部分会细说。2.3 完整的消息收发示例我写一个最小可运行的发送-接收程序。发送进程创建队列并写入消息接收进程按类型取出。发送端代码#include stdio.h #include string.h #include sys/ipc.h #include sys/msg.h struct msgbuf { long mtype; char mtext[64]; }; int main(void) { // 用 ftok 生成一个稳定的 key key_t key ftok(/tmp, 0x01); if (key -1) { perror(ftok); return 1; } int qid msgget(key, IPC_CREAT | 0666); if (qid -1) { perror(msgget); return 1; } struct msgbuf msg; msg.mtype 1; strcpy(msg.mtext, hello from sender); if (msgsnd(qid, msg, strlen(msg.mtext) 1, 0) -1) { perror(msgsnd); return 1; } printf(sent: %s\n, msg.mtext); return 0; }接收端代码#include stdio.h #include sys/ipc.h #include sys/msg.h struct msgbuf { long mtype; char mtext[64]; }; int main(void) { key_t key ftok(/tmp, 0x01); int qid msgget(key, 0666); // 不创建只获取 if (qid -1) { perror(msgget); return 1; } struct msgbuf msg; ssize_t n msgrcv(qid, msg, sizeof(msg.mtext), 1, 0); // 只取类型1 if (n -1) { perror(msgrcv); return 1; } printf(recv: %s, size%zd\n, msg.mtext, n); return 0; }这里有个细节需要说明msgrcv的msgsz传的是sizeof(msg.mtext)也就是缓冲区正文大小。如果实际消息超过这个值默认会报错E2BIG且不取走消息想截断取走需要加MSG_NOERROR标志。2.4 实际使用中绕不开的几个坑第一坑mtype不能为0发送时mtype必须是正整数。因为msgrcv用0表示“取任意消息”如果你允许mtype0语义就产生二义性。内核在msgsnd里直接拒绝mtype0的请求返回EINVAL。第二坑消息大小限制。默认单条消息最大8192字节msgmax每个队列总容量16384字节msgmnb。发一条1MB的消息直接返回EINVAL需要在/etc/sysctl.conf里调大kernel.msgmax和kernel.msgmnb。做文件传输时最容易踩这个。第三坑接收进程崩溃导致消息丢失。上面提到msgrcv取出消息即删除接收方处理到一半挂了数据就没了。如果业务不能接受这一点要么发送方保留副本用于重发要么处理完主动回一条ack消息。第四坑热词里常说的“消息队列重复消费问题”。在System V消息队列里同一消息只会被一个进程取走从机制上不会重复消费。但有一种情况会造成“看似重复”接收方取走消息后没来得及处理主流程重启重新初始化队列时把遗留消息又收一遍——如果你把队列删除重建那残留的消息自然也没了。所以规范做法是程序启动时先msgctl IPC_RMID清理旧队列再创建新队列避免读到上次运行的残留数据。3. 信号量从概念到PV操作实战3.1 为什么需要信号量信号量解决的是“资源不够分”的问题。用一个整数计数器表示可用资源数量进程要使用资源时先做P操作sem_op-1资源数减一资源数为0时阻塞等待用完做V操作sem_op1资源数加一唤醒等待者。我习惯拿停车场打比方信号量值就是剩余车位。车要进场先申请没车位就在门口排队出来一辆车杆子抬起放一辆进去。多个进程同时有车要进整个流程必须靠内核“原子的P/V”保证不超卖。在System V里信号量并不是单一值而是“信号量集”——一个semid对应一组信号量数量在semget时指定。这种设计适合一次操作同时申请多个资源比如同时锁两个缓冲区避免死锁。3.2 semget / semop / semctl 详解semget创建或获取信号量集int semget(key_t key, int nsems, int semflg);nsems表示集内信号量的个数创建时必填获取已存在的集合时传0就可以。semop做实际PV操作int semop(int semid, struct sembuf *sops, size_t nsops);sops指向一个数组数组元素是sembuf结构体struct sembuf { unsigned short sem_num; // 集合中的下标 short sem_op; // -1 P操作1 V操作0表示等信号量为0 short sem_flg; // 0、IPC_NOWAIT、SEM_UNDO };sem_flg里的SEM_UNDO很关键进程退出时内核自动把该进程对信号量做的所有操作“反向补偿”。比如进程P操作把信号量从1改成0之后进程异常崩溃来不及V内核检测到崩溃时自动把信号量加1避免死锁。这个机制对防止“进程挂了导致全局锁死”非常有用建议PV都带上SEM_UNDO。semctl最常用的三个cmdSETVAL用union semun的val给指定信号量赋初值。GETVAL读取当前信号量值。IPC_RMID删除信号量集。注意union semun没有标准定义System V的头文件里经常要求你自己声明常见写法union semun { int val; struct semid_ds *buf; unsigned short *array; };3.3 一个生产者-消费者互斥示例下面用信号量实现一个简单的资源保护场景。多个进程同时对共享资源比如一个设备文件写数据信号量保证同时只有一个进程在临界区。初始化信号量#include stdio.h #include sys/ipc.h #include sys/sem.h union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main(void) { key_t key ftok(/tmp, 0x02); int semid semget(key, 1, IPC_CREAT | IPC_EXCL | 0666); if (semid -1) { perror(semget); return 1; } union semun su; su.val 1; // 初始可通行 if (semctl(semid, 0, SETVAL, su) -1) { perror(semctl SETVAL); return 1; } printf(semaphore initialized, semid%d\n, semid); return 0; }使用信号量#include stdio.h #include sys/ipc.h #include sys/sem.h void P(int semid) { struct sembuf sb {0, -1, SEM_UNDO}; semop(semid, sb, 1); } void V(int semid) { struct sembuf sb {0, 1, SEM_UNDO}; semop(semid, sb, 1); } int main(void) { key_t key ftok(/tmp, 0x02); int semid semget(key, 1, 0666); if (semid -1) { perror(semget); return 1; } P(semid); // 临界区写文件、操作硬件等 printf(in critical section\n); V(semid); return 0; }这段代码里最关键的是SEM_UNDO。如果不加进程异常退出时信号量停在0其他进程永远进不了临界区加了之后内核自动恢复进程崩溃也能自动解锁。这也是System V信号量比裸计数器可靠的核心原因。3.4 SEM_UNDO 与信号量初始化的细节再单独强调一下信号量初始化顺序。信号量刚创建时集内每个信号量值是不确定的可能是残留值必须先semctl SETVAL设置成目标值再让其他进程去获取使用。如果一创建就直接放给别的进程用它们可能看到一个残留的垃圾值逻辑直接混乱。另外有一个隐藏坑SEM_UNDO是“按进程记账”的。如果一个进程做了两次Pundo值就是-2崩溃恢复时一次加2。这个逻辑本身没有问题但如果你在同一进程里对同一个信号量反复P/V最终undo归零不会误伤。真正要小心的是父子进程fork之后undo记录会复制给子进程子进程退出时只补偿它自己做的那部分。这块逻辑想明白不难但面试时经常有人在这里说错。4. 常见问题与排查技巧实录4.1 资源残留与清理ipcs和ipcrm我最常碰到的现场问题是程序退出后队列和信号量仍然占用内核资源。尤其开发阶段反复启动、强杀进程几天下来ipcs一看一堆废弃队列。排查三步走# 查看所有 IPC 对象 ipcs -a # 只看消息队列 ipcs -q # 只看信号量 ipcs -s # 删除指定队列 ipcrm -q msqid # 删除指定信号量集 ipcrm -s semid开发机上想一次性清掉所有队列还可以用脚本ipcs -q | awk /^[0-9]/ { print $2 } | xargs -I {} ipcrm -q {}注意这个命令会把系统里所有队列都删掉生产环境慎用。开发机上图省事倒是常用。4.2 进程阻塞与EIDRM有次现场报障一个后台进程不落日志了。我去排查发现发送端一直往队列里灌消息但接收端因为某种原因没起来队列很快写满发送端所有线程阻塞在msgsnd上。当时处理办法先确认接收端为什么没起恢复接收端进程队列空间自然释放发送端自动恢复。这就是阻塞模式的好处——你不用重启发送方链路通了它会自己继续跑。反过来如果接收端正在msgrcv等待管理员在别的终端执行了ipcrm删除队列接收端会从内核返回errno为EIDRM。代码里必须处理这个错误码否则会误以为网络故障或消息格式错误方向查错。这算是我拿时间换来的教训。4.3 信号量死锁的定位与预防信号量最经典的死锁进程A持有信号量S1等待S2进程B持有S2等待S1。两边都阻塞系统挂起。定位方法用ipcs -s看每个信号量的当前值semval和等待进程数SemNcnt。谁的semval是0但SemNcnt大于0谁就是被卡住的资源。预防手段统一加锁顺序所有进程必须先P(S1)再P(S2)不要有反向顺序。使用semop一次提交多个操作把“先P(S1)再P(S2)”放到同一个sops数组里内核保证这一组操作原子执行不存在“拿到S1还没拿S2”的中间态。这是System V信号量集设计最大的价值。给semop加IPC_NOWAIT拿不到资源立即返回配合重试逻辑避免无期限阻塞。4.4 面试官常问的几个点我把常见问题整理成一张速查表面试前一晚过一遍很有用问题参考答案要点System V消息队列和管道有什么区别管道是字节流无边界消息队列按类型组织、有边界消息队列可多个读进程一条消息只被消费一次msgsnd和msgrcv的阻塞条件队列满时msgsnd阻塞或EAGAIN队列空时msgrcv阻塞或EAGAINmtype可以取0吗发送时不允许接收时mtype0表示任意类型SEM_UNDO的作用进程异常退出时自动还原信号量操作避免锁死如何列出/删除IPC对象ipcs -q/-s、ipcrm -q/-s消息队列重复消费可能吗同一消息只有一个接收者能取走但接收后崩溃会丢失属于至少一次/至多一次的取舍还有一个加分项能说出来kernel.msgmnb、kernel.msgmni这些内核参数在哪调面试官会觉得你真的干过系统调优。这块下一节展开。5. 内核参数调优与调试经验5.1 消息队列和信号量的几个内核参数生产环境里默认值往往不够用。我曾经在数据采集系统里遇到过消息发不出去查了半天发现是kernel.msgmnb默认16KB挡了路——每条消息8KB队列里只能放两条。解决方案是在/etc/sysctl.conf里改kernel.msgmnb 65536 kernel.msgmax 65536 kernel.msgmni 1024改完执行sysctl -p生效。各参数含义kernel.msgmax单条消息最大字节数默认8192。kernel.msgmnb队列总字节上限默认16384。kernel.msgmni系统最多同时存在的消息队列数量默认随内存变化。kernel.sem四个值依次是semmsl每集信号量最大数、semmns系统信号量总数、semopm每次semop最多操作数、semmni系统信号量集最大数。调参原则是不要无脑放大考虑内存占用。每条消息都存在内核里队列越大内存越吃紧。一般建议单条消息不超过16KB总容量按业务峰值估算留1.5倍余量。5.2 排查问题的几个调试技巧最后分享几个我自己常用的调试手段。第一个用/proc文件系统直接看状态cat /proc/sysvipc/msg cat /proc/sysvipc/sem这两个文件以可读文本形式列出所有消息队列和信号量对象字段比ipcs更详细包含最后操作进程PID。找“谁动了我的队列”时特别好用。第二个strace定位API层面的错误。有现场反馈收发消息失败我直接strace -p跟踪目标进程抓到一行msgsnd(458752, ..., 4096, 0) -1 EAGAIN (Resource temporarily unavailable)EAGAIN说明发送端用了IPC_NOWAIT且队列满了立即就能定位到容量问题。第三个养成程序退出清理的习惯。每个用IPC的进程在main函数注册atexit或在退出路径上调用清理函数msgctl(qid, IPC_RMID, NULL)、semctl(semid, 0, IPC_RMID)。团队开发时大家都这么干就能少很多互相“锁死资源”的麻烦。实际上做IPC调优到最后你会发现代码逻辑本身往往不是最难的部分最难的是资源管理和并发时序的掌控。我踩过的最难忘的坑是在一个多进程采集系统里因为忘了清理信号量导致另一个团队的服务拿不到资源排查了整整一天。后来我们立了一条规矩所有涉及IPC的模块必须有明确的“生命周期owner”——谁创建、谁清理、谁在异常时兜底写进代码注释里。System V IPC本身不复杂复杂的是人和进程之间的协作。希望这篇内容能帮你少走点弯路代码写得少一点排查问题快一点。

相关新闻

HDFS底层原理剖析:从Block切片到安全模式的完整链路

HDFS底层原理剖析:从Block切片到安全模式的完整链路

写这篇文章的起因,是最近在带团队做数据平台迁移时,又被问了一轮关于 HDFS 底层原理的问题。说实话,很多同学能背出“NameNode 管元数据、DataNode 管数据、文件按 Block 存储”这套结论,但一旦被问到“为什么 Block 要设计成 128…

2026/10/5 7:17:38 阅读更多 →
Spark实时监控体系建设实战:从指标设计到告警降噪

Spark实时监控体系建设实战:从指标设计到告警降噪

去年双十一前的某个深夜,平台值班群突然炸了。离线数仓的 Spark 任务从晚上八点开始大面积失败,等我们发现问题时,数据看板已经断了快三个小时。最尴尬的是,点开 Spark Web UI,单个任务的执行情况都能看到,…

2026/10/5 7:17:38 阅读更多 →
Claude Code 提示词工程实战:从配置到Agent高效协作

Claude Code 提示词工程实战:从配置到Agent高效协作

最近后台不少读者都在问同一个问题:Claude Code 到底该怎么配提示词,为什么别人用起来像多了个结对程序员,自己用起来却像个只会复述需求的话痨。坦率讲,差别不在工具本身,而在提示词工程。很多人把提示词工程理解成“…

2026/10/5 7:17:38 阅读更多 →

最新新闻

P2G与碳捕集热电联供系统双目标优化及epsilon约束算法Matlab复现

P2G与碳捕集热电联供系统双目标优化及epsilon约束算法Matlab复现

1. 复现背景与核心价值拆解先说结论:这篇论文的复现难度在同类综合能源系统优化文章里算中上,但它值得做。为什么?因为它把两个容易被人忽略的约束同时摆上了桌——碳排放成本和运维成本,而且用的是求解双目标问题的epsilon约束算…

2026/10/5 8:26:10 阅读更多 →
基于策略的访问控制(PBAC)实战指南:在 API 设计中落地策略化授权

基于策略的访问控制(PBAC)实战指南:在 API 设计中落地策略化授权

文档教程知识库 【免费下载链接】developer-roadmap Interactive roadmaps, guides and other educational content to help developers grow in their careers. 项目地址: https://gitcode.com/GitHub_Trending/de/developer-roadmap 点击查看 免费下载 导读&…

2026/10/5 8:26:10 阅读更多 →
油气工地AI视频监管落地全链路:从边缘接入到报警闭环

油气工地AI视频监管落地全链路:从边缘接入到报警闭环

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

2026/10/5 8:26:10 阅读更多 →
Simulink枚举类型在MBD开发中的全面指南:定义、建模与代码生成

Simulink枚举类型在MBD开发中的全面指南:定义、建模与代码生成

1. MBD开发中为什么离不开枚举类型做MBD开发这些年,Simulink里最容易被低估、却实实在在帮我避开无数坑的一个基础能力,就是枚举类型。早期我做VCU整车控制器建模的时候,状态机里明文写数字状态,比如0代表上电、1代表待机、2代表运…

2026/10/5 8:26:10 阅读更多 →
含P2G与碳捕集的综合能源系统双目标优化及Matlab实现

含P2G与碳捕集的综合能源系统双目标优化及Matlab实现

这个标题我在圈子里看到过很多次,说直白点就是一篇关于“有P2G和碳捕集的综合能源系统运行优化”的SCI复现工作,难点不在于把模型跑通,而在于把双目标(碳排放成本运维成本)的求解逻辑理清楚。这类系统里,热…

2026/10/5 8:26:10 阅读更多 →
VirtualBox增强功能安装避坑:版本、内核头文件与Secure Boot全解

VirtualBox增强功能安装避坑:版本、内核头文件与Secure Boot全解

简介:针对虚拟机软件安装增强功能时频繁遇到编译失败、内核源码缺失等报错,这份《VirtualBox安装增强功能的终极办法》系统整理了一套高成功率解决方案,适合在Ubuntu等Linux主机上运行虚拟机、并为CentOS等客户机配置增强功能的虚拟化使用者和…

2026/10/5 8:25:10 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

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

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

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

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →