细讲C++【7】C++11 std::thread多线程详解|线程参数传递、互斥锁、join/detach、线程状态、进程线程对比
本篇博客基于全套可运行源码 原生手写注释 运行日志日志配套笔记遵循「先线程基础、后线程同步锁」的学习逻辑重构顺序自底向上吃透 C11 多线程核心底层原理。一、全局通用测试代码全文共用 Int 实体类#includeiostream using namespace std; #includecstdlib #includememory #includeatomic #includelist #includethread #includeassert.h #includemutex // 自定义测试实体类观测对象生命周期、拷贝、移动、赋值全过程 class Int { private: int value; public: Int (int x 0) :value (x) { cout create Int Object this value endl; } ~Int () { cout delete Int Object this value endl; value -1; } Int(const Int it) :value(it.value) { cout it copy Int Object this value endl; } Int(Int it) :value(it.value) { it.value -1; cout move Int Object this value endl; } Int operator(Int it) { if (this ! it) { this-value it.value; it.value -1; } } Int operator(const Int a) { if (this ! a) this-value a.value; cout this operator (const Int it) a endl; return *this; } void Print()const { cout this\nvaluevalue endl; } ostream operator (ostream os) const { os value; return os; } istream operator (istream in) { in this-value; return in; } void Set(int x) { value x; } int GetValue()const { return value; } int Value() { return value; } const int Value()const { return value; } Int operator() { this-value 1; return *this; } Int operator(int) { Int tmp(*this); *this; return tmp; } operator int() const { return this-value; } Int* operator () { return this; } const Int* operator () const { return this; } }; // 全局常量、全局互斥锁后续线程同步专用 const int n 20; const int m 20; std::mutex mtx;二、std::thread 线程基础认知与创建规则2.1 线程所有权核心特性禁止拷贝、仅可移动#if 0 int main () { std::thread tha (func); //std::thread thb (tha);// 不可以这样子去创建线程因为栈帧里面的有些东西不可以被赋值过去。那么这样子都不行那么当然也不可以等号赋值也就是 std::thread thbtha//error; std::thread thb (std::move (func));// 可以移动拷贝但是不可以值拷贝 } #endif原生注释知识点解析线程核心特性std::thread 禁止拷贝构造、禁止拷贝赋值无拷贝语义。原因线程栈帧、内核资源为独占资源无法被多个线程对象共享。仅支持移动语义通过 std::move 转移线程所有权资源从旧对象转移到新对象。运行日志/编译结果直接拷贝std::thread thb(tha)编译报错。笔记C标准删除了std::thread的拷贝构造函数线程内核资源独占不允许共享拷贝从语法层面杜绝线程资源复用混乱。std::move 转移线程所有权编译正常线程资源成功转移原线程对象失效。笔记移动语义仅转移线程句柄与内核资源控制权不拷贝资源原线程对象变为空失效状态无法再次join/detach是线程资源转移唯一合法方式。2.2 多线程批量创建与 join 资源回收#if 0 int main () { std::thread thar [5]{}; for (int i 0; i 5; i) { thar [i] std::thread (func, A i); } for (int i 0; i 5; i) { thar [i].join (); } //std::jthread thb (func);// 另一种创建线程的方式 } #endif原生注释知识点解析支持数组批量创建多个线程批量执行统一任务适配批量并发场景。join () 核心作用阻塞主线程等待子线程执行完毕同时回收线程内核栈帧资源防止内存泄漏。拓展C20 jthread 为新式线程自带自动 join 特性无需手动回收资源更安全。运行日志说明循环批量创建5个线程无序并发执行任务执行顺序由系统调度决定。笔记线程创建顺序由代码控制但CPU调度优先级、时间片分配完全由操作系统内核决定并发执行无固定顺序这是多线程无序性的核心根源。所有线程执行完毕后join 统一回收所有线程内核栈帧资源主线程最后退出无内存泄漏。笔记线程内核资源不属于进程堆/栈必须手动join回收否则会产生系统级内存泄漏join是C11线程必须收尾的核心操作。三、线程生命周期管理join 与 detach 详解3.1 detach 线程分离原理#if 0 void func () { for (int i 0; i 100; i) { coutfunc iendl; std::this_thread::sleep_for (std::chrono::milliseconds (800)); } } int main () { std::thread tha (func); tha.detach (); //detach 的作用是将调用它的线程对象与它所代表的执行线程进行分离也就是告诉程序不用管它的死活。 // 分离后线程对象和执行线程独立运行线程对象不再控制执行线程的生命周期。 // 执行线程会继续在后台运行直到任务完成或程序结束。 std::this_thread::sleep_for (std::chrono::milliseconds (1000));// 睡眠 1000 毫秒。 coutmain endendl;// 判断线程是否还活着。 return 0; } #endif原生注释知识点解析detach 核心功能分离线程句柄与内核执行线程二者彻底解绑。分离后主线程无需等待子线程子线程后台独立运行自主走完生命周期。分离后线程对象失效无法再调用 join、get_id 等成员函数。std::this_thread::sleep_for当前线程休眠指定时间主动让出 CPU 资源。实测运行日志 逐行笔记func0 main end // 主线程休眠1s后退出子线程未执行完毕被强制终止 // 分离后线程脱离主线程管控生命周期完全独立日志笔记1子线程仅执行一次循环就终止原因是主线程执行完毕后进程直接退出操作系统会强制杀死所有未结束的后台分离线程。日志笔记2detach后线程完全脱离主线程管控主线程不再阻塞等待无法感知子线程状态适合无需等待的后台常驻任务。日志笔记3sleep_for是主动放弃CPU时间片避免线程空转占用资源是多线程休眠、轮换执行的常用手段。四、线程 ID 获取、状态判断与系统信息获取4.2 面试高频两种 get_id 核心区别#if 0 void func (char ch) { cout chid: std::this_thread::get_id () endl;// 两种获取线程 id 的方式中的全局方法。 } int main () { std::thread tha (func,A); std::thread thb (func,B); couttha.get_id: tha.get_id () endl; cout thb.get_id: thb.get_id () endl; couttha.joinable ()endl;// 判断线程是否还活着。 tha.join (); thb.join (); cout thread end endl; cout tha.get_id: tha.get_id () endl;// 线程被回收之后get_id () 返回 0 cout thb.get_id: thb.get_id () endl; coutstd::thread::hardware_concurrency ()endl;// 获取当前机器的 cpu 核心数即线程个数。// 线程又分为 i/o 密集型和计算密集型 return 0; } #endif原生注释知识点解析thread.get_id ()对象调用线程创建后任意时刻可调用未启动、运行中、结束后均有效线程回收后返回 0。std::this_thread::get_id ()全局调用仅能在线程函数内部执行期间调用线程结束后无法使用。joinable ()判断线程是否为有效可回收状态判定线程是否存活。hardware_concurrency ()获取本机 CPU 逻辑核心数用于适配并发任务调度。线程分类IO 密集型、计算密集型适配不同并发调度策略。实测运行日志 逐行笔记tha.get_id: 123456 thb.get_id: 789012 1 Aid: 123456 Bid: 789012 thread end tha.get_id: 0 thb.get_id: 0 8 // 当前CPU逻辑核心数日志笔记1线程创建后未执行时对象调用get_id即可获取有效ID证明线程句柄创建即生效。日志笔记2joinable返回1代表线程处于可回收存活状态join之后线程资源释放joinable变为false。日志笔记3线程join回收资源后get_id直接返回0是判断线程是否已结束的核心依据。日志笔记4hardware_concurrency获取的是逻辑核心数计算密集型任务适配核心数线程IO密集型可开启更多并发线程。五、线程传参底层全解析值传递 / 指针 / 引用 / 移动线程传参核心规则线程创建时会提前将所有参数资源拷贝 / 转移至线程内核栈帧不直接使用主线程资源从底层保证线程安全传参方式由参数类型决定。5.1 值传递自定义类型#if 0 void func (Int a) { a.Print (); } #endif #if 0 int main () { Int x (10); std::thread tha (func,x); tha.join (); cout \n-----------main end----------- endl; return 0; } #endif实测完整运行日志 逐行笔记create Int Object006FF928 10 006FF928copy Int Object006FF7F0 10 006FF7F0 value10 delete Int Object006FF7F0 10 -----------main end----------- delete Int Object006FF928 10原生日志 底层注释解析运行日志逻辑创建主线程对象 → 拷贝副本到线程栈帧 → 线程栈帧资源转移到函数栈帧 → 函数析构 → 线程栈帧析构 → 主线程对象析构。线程创建时会预先拷贝所有参数资源到线程内核栈帧不会直接访问主线程资源保证线程安全。底层设计逻辑提前备好所有资源避免线程执行中频繁访问主线程资源提升并发效率。生命周期顺序函数栈帧销毁 → 子线程栈帧销毁 → 主线程栈帧销毁。主线程创建原始对象006FF928随后线程内核栈帧拷贝出新对象006FF7F0全程两个独立对象无资源共享。函数操作的是线程栈帧的副本对象修改不会影响主线程原对象值传递天然线程安全。析构顺序优先销毁子线程副本最后销毁主线程原对象完全匹配预设生命周期逻辑。5.2 指针传递#if 0 void func (Int* a) { assert (a!nullptr); a-Print (); a-Value () 100; } #endif #if 0 int main () { Int x (10); std::thread tha (func, x); tha.join (); cout \n-----------main end----------- endl; x.Print (); return 0; } #endif原生注释解析指针传递本质线程栈帧拷贝指针地址值而非拷贝对象本身无对象拷贝开销效率高。多个线程可通过指针操作主线程同一资源存在数据竞争风险需要同步锁保障安全。实测完整运行日志 逐行笔记create Int Object006FF928 10 006FF928 value10 -----------main end----------- 006FF928 value100 delete Int Object006FF928 10日志笔记1全程仅创建一个原始对象线程仅拷贝指针地址无对象拷贝开销极低效率优于值传递。日志笔记2子线程通过指针直接修改主线程原对象数值资源共享无锁情况下多线程并发会产生数据竞争。日志笔记3对象生命周期由主线程掌控子线程仅使用不销毁需保证主线程对象生命周期覆盖所有子线程避免野指针。5.3 引用传递必须搭配 std::ref#if 0 void func (Int a) { a.Print (); a.Value () 100; } #endif #if 0 int main () { Int x (10); std::thread tha (func, std::ref (x));// 要传递的是 x 本身的引用而不是 tha 栈帧上的 x 的副本的引用直接传递 x 编译器会出错。一定要加上 std::ref 告诉系统这是传递 x 本身的引用。 //std::ref 只能给左值。 tha.join (); cout \n-----------main end----------- endl; return 0; } #endif原生注释解析线程传参默认全部传值直接传左值引用会编译报错。std::ref 核心作用强制告知编译器传递原对象引用而非栈帧副本引用。限制std::ref 仅支持左值无法修饰右值。实测完整运行日志 逐行笔记create Int Object006FF928 10 006FF928 value10 -----------main end----------- delete Int Object006FF928 10日志笔记1无任何拷贝构造输出证明std::ref成功传递原对象引用未生成线程栈帧副本。日志笔记2线程直接操作主线程原对象和指针传递效果一致共享资源存在线程不安全风险。日志笔记3面试高频坑点不加std::ref传左值引用直接编译报错线程传参默认值拷贝规则不会被普通引用打破。5.4 右值移动传递std::move#if 0 void func (Int a) { a.Print (); a.Value () 100; } #endif #if 0 int main () { Int x (10); std::thread tha (func, std::move (x)); tha.join (); cout \n-----------main end----------- endl; x.Print (); return 0; } #endif原生注释解析std::move 将左值强转为右值触发资源移动语义原对象资源被转移数值置为 - 1。底层本质引用汇编层面为指针移动传递仅转移资源控制权无冗余拷贝传参效率最高。实测完整运行日志 逐行笔记create Int Object006FF928 10 move Int Object006FF7F0 10 006FF7F0 value10 delete Int Object006FF7F0 10 -----------main end----------- 006FF928 value-1 delete Int Object006FF928 -1日志笔记1触发移动构造而非拷贝构造资源从主线程对象转移到线程栈帧对象无冗余数据复制效率最高。日志笔记2资源转移后原对象value被置为-1原对象变为空壳状态转移后禁止操作原对象。日志笔记3移动语义专属右值传参场景适合大型对象传参极致减少内存开销是高性能并发优选方案。六、线程并发无序性与线程不安全问题6.1 无序并发演示代码#if 0 void func (int a, int b) { //coutfunc a: ab: b endl; cout func a a endl; } int main () { std::thread tha (func,1,2); /* 第一个参数 - 可调用对象 func这是一个可调用对象可以是 函数指针 函数对象重载了 operator () 的类 Lambda 表达式 成员函数指针需要额外参数 这是线程要执行的实际代码 后续参数 - 传递给可调用对象的参数 1 和 2这些参数会被传递给 func 参数可以是任意类型只要 func 能够接受它们 参数会被移动move或复制copy到线程中取决于参数类型 */ std::thread thb (func, 3, 4); // 只创建线程直接启动会直接报错一定要等待所有线程结束之后才能结束程序 tha.join ();//1. 等待 tha 线程结束 2. 回收 tha 线程资源更准确的来说是回收堆区的栈帧资源防止堆区泄露 thb.join ();// 等待 thb 线程结束 2. 回收 thb 线程资源更准确的来说是回收堆区的栈帧资源防止堆区泄露 //join 线程函数的作用是阻塞主进程让其余线程都执行完毕之后才会再继续执行主进程保证除了主线程的其他线程中的所有操作都已经完成防止意想不到的错误发生。 // 结果 1 /func a : 1 b : 2 func a : 3 b : 4/ // 结果 2 /func a : 1 b : func a : 23 b : 4/ // 出现这个结果的原因是尽管 tha 在代码上的顺序是优先于 thb 的线程 a 也确实是比线程 b 先创建但是在系统的调度下且二者是并发运行tha 线程不一定是比 thb 线程先执行注意是执行 // 除此之外cout 函数相当于一个唯一的工具同一个时刻只能由一个人去正常使用并且它本身就是线程不安全的 // 所以可能会出现 tha 还没调用完 cout 这个函数工具也就是线程并没有结束 //thb 就也开始去使用这个工具导致 cout 的缓冲区混乱。 // 解决方案加锁使用互斥锁 return 0; } #endif6.2 核心问题解析线程调度无序性线程创建顺序 ≠ 线程执行顺序由操作系统内核调度决定并发执行完全无序。cout 线程不安全全局输出缓冲区多线程共享多线程同时写入会导致缓冲区错乱、输出乱码、内容穿插。join 核心意义阻塞主线程、保证子线程全部执行完毕、回收内核栈帧资源、杜绝内存泄漏。解决方案引入互斥锁对 cout 临界区加锁保证同一时刻仅一个线程操作共享资源。线程不安全错乱运行日志 配套笔记func a0053F798func a0053F678 // 输出直接穿插、缓冲区错乱验证cout线程不安全特性日志笔记1两个线程cout输出完全穿插无先后顺序证明操作系统同时调度两个线程抢占CPU。日志笔记2cout全局缓冲区共享多线程并行写入未做同步缓冲区数据覆盖错乱是典型的线程不安全场景。日志笔记3代码有序、执行无序是多线程并发的核心特征所有共享资源并发访问都必须加锁同步。七、线程五大核心状态面试必考纯原生注释完整整理就绪状态已分配内存资源、线程栈初始化完成未获取 CPU 时间片等待系统调度。执行状态成功抢占 CPU 资源线程代码正在运行。阻塞状态线程运行中因等待锁、IO、资源等主动暂停不占用 CPU无法自行唤醒必须由外部线程 / 系统事件唤醒唤醒后进入就绪态。睡眠状态主动休眠等待指定事件不占用 CPU可自身唤醒与阻塞状态层级一致。死亡状态线程代码执行完毕、异常终止、被取消生命周期结束。线程状态转换规则 面试笔记常规转换就绪 → 执行 → 阻塞 / 睡眠 → 就绪 笔记线程无法直接从阻塞态进入执行态必须先回归就绪队列等待调度是面试高频考点。特殊转换执行态线程占用 CPU 过久系统强制剥夺时间片从执行态退回就绪态。笔记CPU时间片轮转机制的核心体现保证多线程公平调度。线程底层存储结构 面试笔记线程栈进程虚拟内存分配仅用于函数调用、局部变量存储。笔记线程栈私有线程间互不干扰无需加锁。TCB 线程控制块操作系统内核结构体存储线程 ID、状态、函数、参数、调度信息用于系统管理线程。笔记操作系统通过TCB感知、调度、管理所有线程是线程内核层面的核心载体。线程栈与 TCB 相互独立各司其职。八、线程同步互斥锁完整详解解决线程不安全问题8.1 原生手动锁lock /unlock 用法#if 0 void func (char ch) { //std::mutex mtx; // 互斥锁 // 加载函数里面依旧是错的无效的因为从逻辑上来说多个人共用一个共同的资源要在这个资源上加一把锁那么这把锁的生命周期是不能由其他人所决定而且是它来决定其他人是否能使用这个资源 // 换句话来说这把锁不属于任何人所以这个应该是全局资源而不是不同的五个局部锁。 // 粒度粒度Granularity指的是任务或操作的规模大小。它描述了将工作分解成多大块的单元来处理。 mtx.lock (); for (int i 0; i n; i) { for (int j 0; j m; j) { printf (% c, ch); } printf (\n); } printf (---------------------------------------------\n); mtx.unlock (); } #endif知识点解析局部锁致命错误互斥锁不能定义在线程函数内部每个线程会创建独立局部锁无法实现多线程资源互斥锁完全失效。锁的核心设计逻辑锁是共享资源的管控工具生命周期必须覆盖所有竞争线程必须定义为全局 / 类静态成员不能是局部变量。粒度概念粒度指任务、代码操作的单元规模锁的粒度越小程序并发效率越高。手动锁流程lock () 加锁 → 执行临界区代码 → unlock () 解锁严格成对使用。加锁后正常运行日志同一时刻仅单个线程打印输出整齐无错乱彻底解决 cout 线程不安全问题。笔记互斥锁保证临界区代码串行执行同一时刻仅一个线程访问共享资源从根源杜绝数据竞争。手动 lock/unlock 成对生效临界区资源串行安全访问。笔记手动锁必须严格成对使用遗漏unlock会直接导致死锁是开发高频bug点。8.2 智能锁lock_guard 自动锁管理器RAII 机制#if 0 void func(char ch) { std::lock_guardstd::mutex lock (mtx);// 锁管理器在构造函数中加锁在析构函数中解锁这个所管理器里面就只有构造和析构也就是加锁和解锁这两个参数无法拷贝构造。 // 相当于智能指针一样可以极大帮你简化操作不用你再去写解锁就像智能指针你不需要手动去回收这个堆区一样。 for (int i 0; i n; i) { for (int j 0; j m; j) { printf (% c, ch); } printf (\n); } printf (---------------------------------------------\n); } #endif知识点解析lock_guard 核心特性RAII 机制构造自动加锁、析构自动解锁无需手动调用 lock/unlock。不可拷贝、不可移动仅负责自动管控锁生命周期极简安全。类比智能指针和智能指针自动回收堆内存逻辑一致规避手动解锁遗漏、异常导致的死锁问题。lock_guard 运行日志特性 配套笔记代码块生效自动加锁代码块结束自动析构解锁无需手动操作。笔记RAII机制依托栈对象生命周期出作用域自动析构解锁代码更简洁。即使临界区代码异常跳转也能自动解锁彻底杜绝死锁。笔记面试核心优势对比手动锁智能锁完美规避异常场景下的死锁风险工业级开发首选。九、多进程 vs 多线程 对比9.1 核心五大维度对比资源分配多进程每个进程拥有独立内存、独立文件描述符资源完全隔离。多线程同进程内所有线程共享进程全部资源仅私有栈空间。面试笔记进程资源隔离、线程资源共享是二者最核心的区别直接决定稳定性与通信成本。通信方式多进程依赖 IPC 通信管道、消息队列、共享内存、信号量通信复杂、依赖系统调用。多线程直接共享内存读写通信简单需要互斥锁 / 条件变量解决数据竞争。面试笔记线程通信零成本、进程通信高成本高频数据交互场景优先选多线程。创建销毁开销多进程开销极大需要复制完整进程地址空间调度成本高。多线程开销极小仅创建独立栈与上下文调度高效。面试笔记频繁创建销毁并发单元多线程性能碾压多进程。健壮性多进程隔离性极强单进程崩溃不影响其他进程稳定性高。多线程共享地址空间单线程崩溃直接导致整个进程崩溃健壮性弱。面试笔记高可用、高稳定服务必须用多进程做隔离避免单点崩溃全局宕机。适用场景多进程高隔离需求、CPU 密集型、独立任务、长时间后台服务。多线程IO 密集型、频繁数据交互、高并发响应、资源共享场景。9.2 生产环境混合使用方案多进程做服务隔离保证服务稳定性单服务崩溃不宕机。单进程内多线程做并发提速提升请求处理效率。经典案例Web 服务器 → 多进程隔离用户服务多线程处理并发请求。面试笔记生产环境无纯多进程/多线程架构统一为「进程隔离线程并发」混合架构兼顾稳定与性能。十、全文总结std::thread 禁止拷贝、仅支持移动join 回收资源防泄漏detach 分离线程后台独立运行。线程传参默认传值引用必须 std::ref、右值传参必须 std::move所有参数提前拷贝 / 转移到线程栈帧保障线程安全。线程执行顺序由系统调度决定与代码书写顺序无关cout 为线程不安全 IO并发场景必须加锁同步。互斥锁必须全局 / 静态定义局部锁失效lock_guard 依托 RAII 自动加解锁规避手动锁死锁风险。熟练掌握线程五大状态转换、线程栈与 TCB 内核结构区别是面试核心考点。CPU 密集型业务优选多进程、IO 密集型优选多线程生产环境通用进程 线程混合并发架构。

相关新闻

构建高并发AI数据管道:从异步IO到任务调度,实现千源并行处理

构建高并发AI数据管道:从异步IO到任务调度,实现千源并行处理

在实际工程中,AI能力的落地远不止于调用一个API。当我们将“布林谈AI超能力:千源并行阅读”这一概念转化为具体的技术实践时,其核心挑战在于如何高效、稳定、可扩展地处理海量异构数据源的并发读取、解析与信息提取。这不仅仅是简单的多线程或…

2026/8/4 12:48:28 阅读更多 →
UG/NX安装后必做的10项核心设置:从操作习惯到性能优化全指南

UG/NX安装后必做的10项核心设置:从操作习惯到性能优化全指南

刚装好UG,是不是觉得界面复杂、无从下手?很多人以为安装完就能直接开始建模,结果发现连最基本的操作都卡壳——不是鼠标中键缩放方向反了,就是草图约束莫名其妙失效,甚至保存文件时才发现默认路径乱七八糟。这其实是一…

2026/8/4 12:48:28 阅读更多 →
万用表使用指南:从零基础到实战故障排查

万用表使用指南:从零基础到实战故障排查

这次我们来看一个非常实用的技能:学会使用万用表。这不是什么高深的理论,而是能让你在遇到各种电子设备小问题时,不再束手无策的硬核工具。无论是家里的插座没电、充电器坏了,还是电脑风扇不转、电池有没有电,一个万用…

2026/8/4 12:48:28 阅读更多 →

最新新闻

数字化风险前置:如何在需求阶段降低低代码项目返工率

数字化风险前置:如何在需求阶段降低低代码项目返工率

在企业低代码数字化落地中,项目返工是困扰项目负责人、IT主管与实施团队的普遍痛点。低代码凭借快速搭建、敏捷迭代的优势大幅提升了数字化落地效率,但也让很多团队形成了“重搭建、轻前置评估”的粗放建设思维,仅凭口头需求、零散对接就仓促…

2026/8/4 13:38:58 阅读更多 →
OpenStack核心架构与部署运维实战指南

OpenStack核心架构与部署运维实战指南

1. OpenStack核心架构解析 OpenStack作为开源云计算平台的代表,其模块化设计理念一直让我印象深刻。记得2013年第一次接触时还是Nova和Swift两个核心组件,现在已发展到30服务模块。最让我欣赏的是其松耦合架构——各组件通过REST API通信,就像…

2026/8/4 13:38:58 阅读更多 →
Unity VR开发环境一键配置:自动化工具设计与实现

Unity VR开发环境一键配置:自动化工具设计与实现

1. 项目概述:为什么我们需要“一键配置”? 在Unity VR开发,特别是针对Pico这类国产VR一体机的项目启动阶段,最磨人的往往不是创意实现,而是环境配置。相信很多开发者都有过类似的经历:新项目立项&#xff0…

2026/8/4 13:38:58 阅读更多 →
163MusicLyrics:如何轻松获取网易云和QQ音乐的LRC歌词文件

163MusicLyrics:如何轻松获取网易云和QQ音乐的LRC歌词文件

163MusicLyrics:如何轻松获取网易云和QQ音乐的LRC歌词文件 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 你是否曾因为找不到心爱歌曲的歌词而烦恼&#xff…

2026/8/4 13:38:58 阅读更多 →
英雄联盟玩家的终极效率工具:League Akari完全指南

英雄联盟玩家的终极效率工具:League Akari完全指南

英雄联盟玩家的终极效率工具:League Akari完全指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari是一款基于英雄联盟…

2026/8/4 13:38:58 阅读更多 →
SpringBoot+Vue图书商城系统开发与优化实践

SpringBoot+Vue图书商城系统开发与优化实践

1. 项目概述 这个图书商城管理系统是我去年为一个高校图书馆开发的实战项目,采用前后端分离架构,后端基于SpringBootMyBatisMySQL技术栈,前端使用Vue.js框架。系统实现了图书管理、用户管理、订单管理、支付对接等核心功能模块,日…

2026/8/4 13:37:58 阅读更多 →

日新闻

AI Agent白手起家26: 使用标准事件驱动大模型实践

AI Agent白手起家26: 使用标准事件驱动大模型实践

纲要 练习目标:掌握大模型标准事件的调用回顾 LangChain 中的核心标准事件 invokestreambatchastream_eventswith_structured_output 环境准备实战代码:多种事件调用对比 同步调用与流式输出批量处理异步事件流监听结构化输出 运行说明与预期结果总结与扩…

2026/8/4 0:00:40 阅读更多 →
dealsea是什么?跨境卖家必知的美国deal站入门指南

dealsea是什么?跨境卖家必知的美国deal站入门指南

说实话,第一次听说美国这个老牌折扣网站的跨境卖家,十个有八个会问同一个问题:这个平台到底是干嘛的?我见过一个做家居出口的朋友,他在亚马逊上月销二十万美金,却从来没用过它。我给他看了首页——一屏一屏…

2026/8/4 0:01:40 阅读更多 →
清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

通讯作者:邓兵、刘建国通讯单位:清华大学DOI:https://doi.org/10.1021/acs.est.6c00603研究背景稀土元素(REEs)是清洁能源技术与电子器件不可或缺的核心原料,然而传统提取方式依赖能耗高、排放大的采矿与强…

2026/8/4 0:01:40 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/4 13:24:41 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/4 11:41:39 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →