当前位置: 首页 > news >正文

indexDB入门到精通

前言
由于开发3D可视化项目经常用到模型,而一个模型通常是几m甚至是几十m的大小对于一般的服务器来讲加载速度真的十分的慢,为了解决这个加载速度的问题,我想到了几个本地存储的。

首先是cookie,cookie肯定是不行的,因为最多以只能存4k,

其次localStorage,最多能存5m(不是一个key的大小,是所有key的总大小最多加起来最多5m),相对于cookie已经打了很多了。但是当遇到大模型还是不够,实际开发中大部分模型都是10m-30m的。

经过网上的相关资料的搜索了解到了indexDB,indexD就正好合适了,因为我发现我常用的3d框架three.js他们也是使用indexDB去做存储,而且存储大小是250m以上(受计算机硬件和浏览器厂商的限制)。

一、直接上代码更看结果更直观

懒人直接看入门的全部代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><title>Title</title><link href="./favicon.png">
</head>
<body>
</body>
<script>let dbName = 'helloIndexDB', version = 1, storeName = 'helloStore'let indexedDB = window.indexedDBlet dbconst request = indexedDB.open(dbName, version)request.onsuccess = function(event) {db = event.target.result // 数据库对象console.log('数据库打开成功')}request.onerror = function(event) {console.log('数据库打开报错')}request.onupgradeneeded = function(event) {// 数据库创建或升级的时候会触发console.log('onupgradeneeded')db = event.target.result // 数据库对象let objectStoreif (!db.objectStoreNames.contains(storeName)) {objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表// objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段}}// 添加数据function addData(db, storeName, data) {let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写").objectStore(storeName) // 仓库对象.add(data)request.onsuccess = function(event) {console.log('数据写入成功')}request.onerror = function(event) {console.log('数据写入失败')throw new Error(event.target.error)}}// 根据id获取数据function getDataByKey(db, storeName, key) {let transaction = db.transaction([storeName]) // 事务let objectStore = transaction.objectStore(storeName) // 仓库对象let request = objectStore.get(key)request.onerror = function(event) {console.log('事务失败')}request.onsuccess = function(event) {console.log('主键查询结果: ', request.result)}}// 根据id修改数function updateDB(db, storeName, data) {let request = db.transaction([storeName], 'readwrite') // 事务对象.objectStore(storeName) // 仓库对象.put(data)request.onsuccess = function() {console.log('数据更新成功')}request.onerror = function() {console.log('数据更新失败')}}// 根据id删除数据function deleteDB(db, storeName, id) {let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)request.onsuccess = function() {console.log('数据删除成功')}request.onerror = function() {console.log('数据删除失败')}}// 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错setTimeout(() => {addData(db, storeName, {id: new Date().getTime(), // 必须且值唯一name: '张三',age: 18,desc: 'helloWord'})getDataByKey(db, storeName, 1638160036008)updateDB(db, storeName, {id: 1638164880484, desc: '修改的内容'})deleteDB(db, storeName, 1638164870439)}, 1000)</script>
</html>

第一步:准备环境和基本的html页面

 基本的html代码

​<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><title>Title</title>
</head>
<body>
</body>
<script></script>
</html>

第二步:打开数据库(如果没有自动创建)

  let dbName = 'helloIndexDB', version = 1, storeName = 'helloStore'let indexedDB = window.indexedDBlet dbconst request = indexedDB.open(dbName, version)request.onsuccess = function(event) {db = event.target.result // 数据库对象console.log('数据库打开成功')}request.onerror = function(event) {console.log('数据库打开报错')}request.onupgradeneeded = function(event) {// 数据库创建或升级的时候会触发console.log('onupgradeneeded')db = event.target.result // 数据库对象let objectStoreif (!db.objectStoreNames.contains(storeName)) {objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表// objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段}}

运行如上面的代码后打开控制台可以看到如下效果,数据库已经创建完成了,此时什么数据都没有

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_19,color_FFFFFF,t_70,g_se,x_16

第三步:存入一个helloWorld 

  // 添加数据function addData(db, storeName, data) {let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写").objectStore(storeName) // 仓库对象.add(data)request.onsuccess = function(event) {console.log('数据写入成功')}request.onerror = function(event) {console.log('数据写入失败')throw new Error(event.target.error)}}// 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错setTimeout(() => {addData(db, storeName, {id: new Date().getTime(), // 必须且值唯一name: '张三',age: 18,desc: 'helloWord'})}, 1000)

刷新页面后可以看到如下结果,此时我这里已经存进去了,(我刷新了两次所以有两条数据)

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_20,color_FFFFFF,t_70,g_se,x_16

 第四步:封装删除,查询,修改方法并分别执行查看结果

 // 根据id获取数据function getDataByKey(db, storeName, key) {let transaction = db.transaction([storeName]) // 事务let objectStore = transaction.objectStore(storeName) // 仓库对象let request = objectStore.get(key)request.onerror = function(event) {console.log('事务失败')}request.onsuccess = function(event) {console.log('主键查询结果: ', request.result)}}// 根据id修改数function updateDB(db, storeName, data) {let request = db.transaction([storeName], 'readwrite') // 事务对象.objectStore(storeName) // 仓库对象.put(data)request.onsuccess = function() {console.log('数据更新成功')}request.onerror = function() {console.log('数据更新失败')}}// 根据id删除数据function deleteDB(db, storeName, id) {let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)request.onsuccess = function() {console.log('数据删除成功')}request.onerror = function() {console.log('数据删除失败')}}// 由于打开indexDB是异步的加个定时器避免 db对象还没获取到值导致 报错setTimeout(() => {// addData(db, storeName, {//   id: new Date().getTime(), // 必须且值唯一//   name: '张三',//   age: 18,//   desc: 'helloWord'// })getDataByKey(db, storeName, 1638160036008)updateDB(db, storeName, {id: 1638164880484, desc: '修改的内容'})deleteDB(db, storeName, 1638164870439)}, 1000)

执行上面的代码后结果后,我这边的结果如下,

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reL6Zuo5LiA55u06LWwfg==,size_20,color_FFFFFF,t_70,g_se,x_16

 二、封装indexDB库,

第一步:封装类库

/*** 封装的方法以及用法* 打开数据库*/
export function openDB(dbName, storeName, version = 1) {return new Promise((resolve, reject) => {let indexedDB = window.indexedDBlet dbconst request = indexedDB.open(dbName, version)request.onsuccess = function(event) {db = event.target.result // 数据库对象resolve(db)}request.onerror = function(event) {reject(event)}request.onupgradeneeded = function(event) {// 数据库创建或升级的时候会触发console.log('onupgradeneeded')db = event.target.result // 数据库对象let objectStoreif (!db.objectStoreNames.contains(storeName)) {objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表// objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段}}})
}/*** 新增数据*/
export function addData(db, storeName, data) {return new Promise((resolve, reject) => {let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写").objectStore(storeName) // 仓库对象.add(data)request.onsuccess = function(event) {resolve(event)}request.onerror = function(event) {throw new Error(event.target.error)reject(event)}})
}/*** 通过主键读取数据*/
export function getDataByKey(db, storeName, key) {return new Promise((resolve, reject) => {let transaction = db.transaction([storeName]) // 事务let objectStore = transaction.objectStore(storeName) // 仓库对象let request = objectStore.get(key)request.onerror = function(event) {reject(event)}request.onsuccess = function(event) {resolve(request.result)}})
}/*** 通过游标读取数据*/
export function cursorGetData(db, storeName) {let list = []let store = db.transaction(storeName, 'readwrite') // 事务.objectStore(storeName) // 仓库对象let request = store.openCursor() // 指针对象return new Promise((resolve, reject) => {request.onsuccess = function(e) {let cursor = e.target.resultif (cursor) {// 必须要检查list.push(cursor.value)cursor.continue() // 遍历了存储对象中的所有内容} else {resolve(list)}}request.onerror = function(e) {reject(e)}})
}/*** 通过索引读取数据*/
export function getDataByIndex(db, storeName, indexName, indexValue) {let store = db.transaction(storeName, 'readwrite').objectStore(storeName)let request = store.index(indexName).get(indexValue)return new Promise((resolve, reject) => {request.onerror = function(e) {reject(e)}request.onsuccess = function(e) {resolve(e.target.result)}})
}/*** 通过索引和游标查询记录*/
export function cursorGetDataByIndex(db, storeName, indexName, indexValue) {let list = []let store = db.transaction(storeName, 'readwrite').objectStore(storeName) // 仓库对象let request = store.index(indexName) // 索引对象.openCursor(IDBKeyRange.only(indexValue)) // 指针对象return new Promise((resolve, reject) => {request.onsuccess = function(e) {let cursor = e.target.resultif (cursor) {list.push(cursor.value)cursor.continue() // 遍历了存储对象中的所有内容} else {resolve(list)}}request.onerror = function(ev) {reject(ev)}})
}/*** 更新数据*/
export function updateDB(db, storeName, data) {let request = db.transaction([storeName], 'readwrite') // 事务对象.objectStore(storeName) // 仓库对象.put(data)return new Promise((resolve, reject) => {request.onsuccess = function(ev) {resolve(ev)}request.onerror = function(ev) {resolve(ev)}})
}/*** 删除数据*/
export function deleteDB(db, storeName, id) {let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)return new Promise((resolve, reject) => {request.onsuccess = function(ev) {resolve(ev)}request.onerror = function(ev) {resolve(ev)}})
}/*** 删除数据库*/
export function deleteDBAll(dbName) {console.log(dbName)let deleteRequest = window.indexedDB.deleteDatabase(dbName)return new Promise((resolve, reject) => {deleteRequest.onerror = function(event) {console.log('删除失败')}deleteRequest.onsuccess = function(event) {console.log('删除成功')}})
}/*** 关闭数据库*/
export function closeDB(db) {db.close()console.log('数据库已关闭')
}export default {openDB,addData,getDataByKey,cursorGetData,getDataByIndex,cursorGetDataByIndex,updateDB,deleteDB,deleteDBAll,closeDB
}

第二步:使用类库,该库的使用方法如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><title>Title</title><link href="./favicon.png">
</head>
<body>
</body>注意要加 type="module"
<script type="module">
-->
<script type="module">import IndexDB from './IndexDB.js'(async function() {const dbName = 'myDB', storeName = 'db_1'const db = await IndexDB.openDB(dbName, storeName, 1)var data = await IndexDB.addData(db, storeName, {id: 111, // 必须且值唯一name: '张三',age: 18,desc: 'helloWord'})console.log(data)var data = await IndexDB.getDataByKey(db, storeName, 111)console.log(data)var data = await IndexDB.updateDB(db, storeName, { id: 111, desc: '修改的内容' })console.log(data)var data = await IndexDB.deleteDB(db, storeName, 111)console.log(data)})()
</script>
</html>

三、使用indexdb第三方类库indexdbwrapper(这种方式需要懂得使用打包工具开发不懂跳过)

/* 下载cnpm install --save indexdbwrapper
*/
// 引入
import IndexDBWrapper from 'indexdbwrapper'
// 使用
async function dbTest() {const dbName = 'dbName', storeName = 'storeName', version = 1const db = new IndexDBWrapper(dbName, version, {onupgradeneeded(event) {const db = event.target.result // 数据库对象let objectStoreif (!db.objectStoreNames.contains(storeName)) {objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表// objectStore.createIndex('createTime', 'createTime', { unique: false }) // 创建索引 可以让你搜索任意字段}}})await db.open()await db.add(storeName, { id: new Date().getTime(), updateTime: new Date().getTime() })console.log(await db.get(storeName, 1639015754840))console.log(await db.put(storeName, { id: 1639015754840, put: 'put2' }))console.log(await db.get(storeName, 1639015754840))console.log(await db.delete(storeName, 1639015754840))// console.log(await db.clear(storeName))
}
dbTest()

相关文章:

indexDB入门到精通

前言 由于开发3D可视化项目经常用到模型&#xff0c;而一个模型通常是几m甚至是几十m的大小对于一般的服务器来讲加载速度真的十分的慢&#xff0c;为了解决这个加载速度的问题&#xff0c;我想到了几个本地存储的。 首先是cookie,cookie肯定是不行的&#xff0c;因为最多以只…...

Ubuntu 20.04配置静态ip

ip配置文件 cd /etc/netplan配置 根据需求增加 # Let NetworkManager manage all devices on this system network:version: 2renderer: NetworkManager # 管理 不是必须ethernets:enp4s0: #网卡名dhcp4: no #关闭ipv4动态分配ip地址dhcp6: no #关闭ipv6动态分配…...

Tushare入门小册

Tushare入门小册 一、Tushare平台介绍 Pro版数据更稳定质量更好了&#xff0c;我们提供的不再是直接从互联网抓取&#xff0c;而是通过社区的采集和整理存入数据库经过质量控制后再提供给用户。但Pro依然是个开放的&#xff0c;免费的平台&#xff0c;不带任何商业性质和目的…...

<c++开发>通信工具 -之-SOME/IP移植部署 第一篇文章

&#xff1c;c开发&#xff1e;通信工具 -之-SOME/IP移植ubuntu部署 第一篇文章 一 前言 SOME/IP (Scalable service-Oriented MiddlewarE over IP) 是一种通信协议&#xff0c;主要用于嵌入式系统和车载网络中的服务导向通信。SOME/IP是AUTOSAR&#xff08;AUTomotive Open …...

权威的软件测试服务供应商分享,怎么获得软件安全检测报告?

我们深知在如今的数字化时代&#xff0c;软件安全对于企业和个人来说具有极其重要的意义。然而&#xff0c;许多用户对于软件安全测试报告的概念还不够清晰&#xff0c;也不知道如何获得这样的报告。在本文中&#xff0c;小编将为您简析什么是安全测试报告以及如何获取这样的报…...

管理类联考——逻辑——真题篇——按知识分类——汇总篇——二、论证逻辑——假设——第二节——搭桥假设

文章目录 第二节 假设-分类1-搭桥假设-当题干推理存在明显断点,常见形式比如:“因为A→B,C→D,所以A→D”,则正确选项为“B→C”真题(2014-39)-假设-分类1-题干推理存在明显断点-搭桥假设-建模搭桥-“因为A→B,所以A→C”,搭桥假设为“B→C”真题(2019-44)-假设-分…...

百度云BOS云存储的图片如何在访问时,同时进行格式转换、缩放等处理

前言 之前做了一个图片格式转换和压缩的服务&#xff0c;结果太占内存。后来查到在访问图片链接时&#xff0c;支持进行图片压缩和格式转换&#xff0c;本来想着先格式转换、压缩图片再上传到BOS&#xff0c;现在变成了上传后&#xff0c;访问时进行压缩和格式转换。想了想&am…...

go生成文件md5、sha1摘要简单示例

备注 go官方文档 https://pkg.go.dev/crypto/md5 已经给出如何使用该package生成文件或者字节数组的摘要值&#xff0c; 参照即可。 摘要值不是对文内容的加密&#xff0c;它主要用来进行checksum&#xff0c;就是验证两个文件内容是否一致&#xff0c;是否被篡改或者变化了。…...

Docker容器:docker数据管理、镜像的创建及dockerfile案例

文章目录 一、docker数据管理1.为何需要docker数据管理2.数据管理类型3.数据卷4.数据卷容器5.容器的互联 二.docker镜像的三种创建方法1.基于现有镜像创建1.1 启动镜像1.2 生成新镜像 2.基于本地模板创建2.1 OPENVZ 下载模板2.2 导入容器生成镜像 3.基于dockerfile创建3.1 dock…...

Ajax fetch Axios 的区别

AJAX&#xff1a;一种创建交互式网页应用的网页执行交互技术 通过在后台与服务器进行少量数据交换&#xff0c;Ajax可以使网页实现异步更新。意味着&#xff1a;在不重新加载整个网页 的情况下&#xff0c;对网页某部分进行更新。 缺点&#xff1a; 针对MVC编程&#xff0c;…...

数据库结构差异对比工具

简介 前几年写了一个数据库对比工具&#xff0c;但是由于实现方式的原因&#xff0c;数据库支持有限&#xff0c;所以重新设计了一下&#xff0c;便于支持多种数据库&#xff0c;并且更新了UI。 新版地址&#xff1a;https://gitee.com/xgpxg/db-diff 旧版地址&#xff1a;h…...

Shell编程学习之breakcontinuereturn的应用

Shell编程中的break关键字&#xff1a;break关键字&#xff1a;退出最近的循环&#xff0c;后续循环不再执行&#xff1b;break关键字用法&#xff1a; break #结束本层循环 break 数字n #结束n层循环测试代码1&#xff1a; #!/bin/bashfor((i1;i<6;i)) dofor((…...

有趣的数学 数学建模入门二 一些理论基础

一、什么是数学建模? 现实世界中混乱的问题可以用数学来解决&#xff0c;从而产生一系列可能的解决方案来帮助指导决策。大多数人对数学建模的概念感到不舒服&#xff0c;因为它是如此开放。如此多的未知信息似乎令人望而却步。哪些因素最相关&#xff1f;但正是现实世界问题的…...

Spring复习:(55)ApplicationContext中BeanFactoryPostProcessor是怎么添加到容器的?

容器创建时会调用AbstractApplicationContext的refresh方法&#xff0c;其中会调用invokeBeanFactoryPostProcessor方法&#xff0c;如下图 invokeBeanFactoryPostProcessors代码如下&#xff1a; 其中调用的PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcess…...

给wordpress添加关键词与描述

Wordpress网站的关键字及网页描述关系网站对搜索引擎的友好程度&#xff0c;如果自己手动加显然太折腾了&#xff0c;那如何让WordPress博客自动为每篇文章自动关键字及网页描述。每篇文章的内容不同&#xff0c;我们该如何让wordpress自动添加文章描述和关键词呢&#xff1f;下…...

Verilog 入门

Verilog 入门 本内容来自 牛客网Verilog入门特别版 1、一个没有输入和一个输出常数1的输出的电路&#xff0c;输出信号为one module top_module(one);output wire one;assign one 1b1; endmodule2、创建一个具有一个输入和一个输出的模块&#xff0c;其行为类似于电路上的连…...

shell 简单且常用的几种

目录 一、配置环境的shell脚本 二、系统资源脚本 一、要求 二、脚本内容 三、脚本解析 四、赋权并验证 三、查看当前内存的总大小、实际使用大小、剩余大小、显示使用率百分比的脚本 一、第一种方法 二、验证 三、第二种方法 四、验证 四、查看网卡实时流量脚本 一…...

redis基本介绍以及在node中使用

文章目录 引言一、什么是redis1. redis简介2. redis的特点3. redis的应用场景 二、redis在windows下安装1. 下载安装2.验证是否安装成功3. 配置环境变量 三、redis-cli常用命令介绍1. redis-cli2. keys *3. set key value4. get key5. exists key6. del key7. info8. flushdb9.…...

React Native 文本输入基础知识

在 React Native 中提供了一个文本输入组件TextInput。此组件主要是监听键盘输入事件&#xff0c;并把对应的输入值显示在组件中&#xff0c;此组件还提供了很多功能配置参数&#xff0c;例如自动更正、自动大写、占位符文本和不同的键盘类型&#xff08;例如数字键盘&#xff…...

qt显示图片并转换成灰度图及伪彩图

写了个程序&#xff0c;可在途图片&#xff0c;并切换成灰度图及伪彩图显示&#xff0c;主要代码如下&#xff1a; #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainW…...

大疆上云API Demo停更了,我们手里的老项目该怎么办?(附迁移思路与安全加固建议)

大疆上云API停更后&#xff1a;老项目的风险评估与迁移实战指南 当官方宣布停止维护某个关键组件时&#xff0c;技术团队面临的不仅是代码层面的挑战&#xff0c;更是对系统全生命周期管理能力的考验。最近大疆上云API Demo的停更公告&#xff0c;让许多依赖该接口的无人机应用…...

macOS Sequoia 15.7.5 (24G624) Boot ISO 原版可引导映像下载

macOS Sequoia 15.7.5 (24G624) Boot ISO 原版可引导映像下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接&#xff1a;https://sysin.org/blog/macOS-Sequoia-boot-iso/ 查看最新版。原创作品&#xff0c…...

【2026 最新】 MySQL 数据库安装教程(超详细图文版-纯享版)小白也可以安装成功!

一、前言 MySQL 作为开源关系型数据库的标杆&#xff0c;广泛应用于 Web 开发、数据分析等场景&#xff0c;是程序员必备的基础工具之一。很多新手安装MySQL时都会陷入“版本选择困难症”——版本太高怕兼容出问题&#xff0c;版本太低又缺功能、不支持主流框架&#xff0c;甚…...

vSphere环境安全指南:使用vCenter创建受限用户的最佳实践

vSphere环境安全指南&#xff1a;精细化权限管理实战 在虚拟化基础设施管理中&#xff0c;vSphere环境的安全性直接关系到企业核心业务的稳定运行。作为高级管理员&#xff0c;我们常常面临一个两难选择&#xff1a;既要确保团队成员能够高效完成工作&#xff0c;又要防止过度授…...

Rasa Pro企业级对话AI实战:从安全扫描到密钥管理的完整配置指南

Rasa Pro企业级对话AI实战&#xff1a;从安全扫描到密钥管理的完整配置指南 在金融行业数字化转型浪潮中&#xff0c;智能对话系统已成为客户服务的核心组件。作为Rasa的商业化企业版本&#xff0c;Rasa Pro凭借其专业级的安全防护和可观测性功能&#xff0c;正在成为银行、保险…...

https://docker.m.daocloud.io/v2 访问失败

目录 2. 测试 mirror 能不能访问&#xff08;很关键&#xff09; 正常&#xff1a; 修改docker-compose ① 改 compose ② 拉镜像 ③ 启动 2. 测试 mirror 能不能访问&#xff08;很关键&#xff09; 比如&#xff1a; curl -I https://docker.m.daocloud.io/v2/ 正常&…...

Zephyr RTOS 线程实战:从信号量到消息队列,手把手教你搞定多任务通信

Zephyr RTOS线程通信实战&#xff1a;信号量与消息队列的深度应用指南 在嵌入式开发领域&#xff0c;多任务间的有效通信是构建可靠系统的关键所在。想象这样一个场景&#xff1a;你的物联网设备需要同时处理传感器数据采集、实时数据处理、无线通信传输等多个任务&#xff0c;…...

linux条件变量封装(2026.3.24)

条件变量的wait让线程休眠&#xff0c;Signal随机唤醒一个线程&#xff0c;然后又立马锁上。#include<iostream> #include<pthread.h> #include"Mutex.hpp"namespace CondModule{using namespace MutexModule;class Cond{public:Cond(){pthread_cond_ini…...

OpenClaw配置备份:Qwen3.5-9B模型参数迁移与快速恢复方案

OpenClaw配置备份&#xff1a;Qwen3.5-9B模型参数迁移与快速恢复方案 1. 为什么需要系统化备份OpenClaw配置 上周我的开发机SSD突然故障&#xff0c;导致整个系统需要重装。当我重新部署OpenClaw时&#xff0c;突然意识到一个严重问题&#xff1a;过去三个月精心调试的模型参…...

Sora死了

好莱坞杀死了 Sora&#xff1a;传统行业在 AI 浪潮下的无谓挣扎摘要&#xff1a;2026 年 3 月 24 日&#xff0c;OpenAI 宣布关闭 Sora&#xff0c;距离正式发布仅 6 个月。表面看是迪士尼退出授权协议导致的商业失败&#xff0c;实质是传统内容行业对 AI 技术抵制的缩影。本文…...