Web API 基础 (Web Workers API)

news2024/11/18 7:35:25

Web Workers API

1、指南

1.1 使用Web Workers

Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外,它们还可以使用XMLHttpRequest(尽管responseXMLchannel属性总是为空)或fetch(没有此类限制)执行I/O。工作线程一旦被创建,就可以通过向JavaScript代码指定的事件处理程序发送消息来向创建它的JavaScript代码发送消息(反之亦然)。

本文详细介绍了如何使用web worker。

1.1.1 Dedicated workers

如上所述,Dedicated worker只能由调用它的脚本访问。在本节中,我们将讨论在 Basic dedicated worker example示例中发现的JavaScript:它允许您输入两个要相乘的数字。这些数字被发送给一个专门的工作者,相乘,结果返回到页面并显示。

这个示例相当简单,但我们决定在向您介绍基本的worker概念时保持简单。本文稍后将介绍更高级的细节。

Worker feature detection

为了更好地控制错误处理和向后兼容性,将 worker 访问代码包装在下面(main.js)中是一个好主意:

if (window.Worker) {
  // …
}
Spawning a dedicated worker

创建一个新的worker很简单。您所需要做的就是调用Worker()构造函数,指定要在Worker线程中执行的脚本的URI

// main.js
const myWorker = new Worker("worker.js");
向专用worker发送和从专用worker发送消息

worker的魔力是通过postMessage()方法和onmessage事件处理程序实现的。当您想要向worker发送消息时,您可以像这样向它发送消息

first.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

second.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

这里有两个<input>元素分别由变量firstsecond表示;当其中一个的值被改变时,myWorker.postMessage([first.value,second.value])被用来将两者中的值以数组的形式发送给worker。你可以在消息中发送任何你喜欢的东西。

在worker中,当收到消息时,我们可以通过编写这样的事件处理程序块来响应:

// worker.js
onmessage = (e) => {
  console.log("Message received from main script");
  const workerResult = `Result: ${e.data[0] * e.data[1]}`;
  console.log("Posting message back to main script");
  postMessage(workerResult);
};

onmessage处理程序允许我们在接收到消息时运行一些代码,消息本身在message 事件的data属性中可用。这里我们将两个数字相乘,然后再次使用postMessage(),将结果发送回主线程。

回到主线程,我们再次使用onmessage来响应从worker发送回来的消息:

myWorker.onmessage = (e) => {
  result.textContent = e.data;
  console.log("Message received from worker");
};

这里我们获取消息事件数据并将其设置为result段落的textContent,这样用户就可以看到计算的结果。

结束 worker

如果你需要在主线程中立即终止一个正在运行的worker,你可以通过调用worker的terminate方法来完成:

myWorker.terminate();

工作线程被立即终止。

处理错误

当工作线程中发生运行时错误时,将调用其onerror事件处理程序。它接收一个名为error的事件,该事件实现了ErrorEvent接口。

事件不会冒泡并且可以取消;为了防止默认操作发生,worker可以调用错误事件的preventDefault()方法。

错误事件有以下三个感兴趣的字段:

  • message
    一个人类可读的错误信息。
  • filename
    发生错误的脚本文件的名称。
  • lineno
    发生错误的脚本文件的行号。
Spawning subworkers

如果workers 愿意,他们可能会产生更多的workers 。所谓的子worker必须托管在与父页面相同的源中。此外,子worker的uri是相对于父worker的位置而不是所属页面的位置进行解析的。这使得workers 更容易跟踪他们的依赖项在哪里。

导入脚本和库

工作线程可以访问全局函数importScripts(),该函数允许它们导入脚本。它接受零个或多个uri作为要导入的资源的参数;以下所有例子都是正确的:

importScripts(); /* imports nothing */
importScripts("foo.js"); /* imports just "foo.js" */
importScripts("foo.js", "bar.js"); /* imports two scripts */
importScripts(
  "//example.com/hello.js",
); /* You can import scripts from other origins */

浏览器加载列出的每个脚本并执行它。然后,worker可以使用每个脚本中的任何全局对象。如果无法加载脚本,则抛出NETWORK_ERROR,并且不会执行后续代码。之前执行的代码(包括使用setTimeout()延迟的代码)仍然可以使用。还保留了importScripts()方法之后的函数声明,因为它们总是在其余代码之前求值。

1.1.2 Shared workers

一个共享的工作线程可以被多个脚本访问——即使它们被不同的窗口、iframe甚至工作线程访问。在本节中,我们将讨论基 Basic shared worker example示例中的JavaScript(运行shared worker):这与basic dedicated worker 示例非常相似,除了它有两个可用的函数,由不同的脚本文件处理:两个数字的乘法,或一个数字的平方。两个脚本都使用同一个worker来执行所需的实际计算。

在这里,我们将集中讨论 dedicated workers 和shared workers之间的区别。请注意,在这个示例中,我们有两个HTML页面,每个页面都应用了使用相同工作文件的JavaScript。

生成一个 shared worker

生成一个新的共享工作线程与 dedicated 工作线程非常相似,但使用不同的构造函数名称(参见index.htmlindex2.html) -每个构造函数都必须使用如下代码启动工作线程:

const myWorker = new SharedWorker("worker.js");

一个很大的区别是,对于共享工作线程,您必须通过port 对象进行通信—打开一个显式端口,脚本可以使用该端口与工作线程进行通信(这在 dedicated 工作线程的情况下隐式完成)。

端口连接需要通过使用onmessage事件处理程序隐式启动,或者在发布任何消息之前显式地使用start()方法启动。只有当消息事件通过addEventListener()方法连接时才需要调用start()

注意:当使用start()方法打开端口连接时,如果需要双向通信,则需要从父线程和工作线程都调用该方法。

向共享worker发送消息和从共享worker发送消息

现在消息可以像以前一样发送到worker,但是postMessage()方法必须通过port对象调用(同样,你会在 multiply.jssquare.js中看到类似的结构):

// square.js/multiply.js
squareNumber.onchange = () => {
  myWorker.port.postMessage([squareNumber.value, squareNumber.value]);
  console.log("Message posted to worker");
};

现在,来看看worker。这里也有一点复杂

onconnect = (e) => {
  const port = e.ports[0];

  port.onmessage = (e) => {
    const workerResult = `Result: ${e.data[0] * e.data[1]}`;
    port.postMessage(workerResult);
  };
};

首先,当端口连接发生时,我们使用onconnect处理程序来触发代码(例如,当父线程中的onmessage事件处理程序被设置时,或者当父线程中显式调用start()方法时)。

我们使用该事件对象的ports属性来获取端口并将其存储在一个变量中。

接下来,我们在端口上添加一个onmessage处理程序来执行计算并将结果返回给主线程。在工作线程中设置这个onmessage处理程序也会隐式地打开到父线程的端口连接,因此实际上不需要调用port.start(),如上所述。

最后,回到主脚本,我们处理消息(同样,您将在multi .js和square.js中看到类似的结构)。

// multiply.js and square.js
myWorker.port.onmessage = (e) => {
  result2.textContent = e.data;
  console.log("Message received from worker");
};

当消息通过端口从worker返回时,我们将计算结果插入到适当的结果段落中。

1.2 Web worker可用的函数和类

除了标准的JavaScript函数集(如StringArrayObjectJSON等)之外,还有各种各样的函数可以从DOM中提供给worker。本文提供了一个列表。

Worker Contexts & Functions

工作线程运行在与当前窗口(window)不同的全局上下文中!虽然Window不是直接对worker可用,但许多相同的方法都是在一个共享的mixin (WindowOrWorkerGlobalScope)中定义的,并且通过worker自己的WorkerGlobalScope派生的上下文提供给worker使用:

  • DedicatedWorkerGlobalScope for dedicated workers
  • SharedWorkerGlobalScope for shared workers
  • ServiceWorkerGlobalScope for service workers

一些函数(一个子集)是所有工作线程和主线程(来自WindowOrWorkerGlobalScope)共同的:

  • atob()
  • btoa()
  • clearInterval()
  • clearTimeout()
  • dump() Non-standard
  • queueMicrotask()
  • setInterval()
  • setTimeout()
  • structuredClone()
  • window.requestAnimationFrame (dedicated workers only)
  • window.cancelAnimationFrame (dedicated workers only)

以下函数仅对worker可用:

  • WorkerGlobalScope.importScripts() (all workers)
  • DedicatedWorkerGlobalScope.postMessage (dedicated workers only)

worker中可用的Web APIs

注意:如果列出的API在特定版本中被平台支持,那么通常可以认为它在web worker中可用。您还可以使用网站https://worker-playground.glitch.me/测试对特定对象/函数的支持

1.3 结构化克隆算法

结构化克隆算法复制复杂的JavaScript对象。它在调用structuredClone()时内部使用,通过postMessage()在 worker 之间传输数据,使用IndexedDB存储对象,或为其他api复制对象。

它通过递归遍历输入对象进行克隆,同时维护以前访问过的引用的映射,以避免无限遍历循环。

结构化克隆不适用的东西

  • 函数对象不能被结构化克隆算法复制;试图抛出DataCloneError异常。
  • 克隆 DOM 节点同样会抛出DataCloneError异常。
  • 某些对象属性不保留:
    • 不保留RegExp对象的lastIndex属性。
    • 属性描述符、setter、getter和类似元数据的特性不复制。例如,如果一个对象用属性描述符标记为只读,那么它将在副本中被读/写,因为这是默认的。
    • 原型链(prototype chain)不会被遍历或复制。

支持的类型

JavaScript types
Error types
Web/API types

1.4 Transferable objects

可转移对象(Transferable objects)是拥有资源的对象,这些资源可以从一个上下文中转移到另一个上下文中,从而确保资源一次只在一个上下文中可用。转移后,原对象不再可用;它不再指向传输的资源,并且任何读取或写入该对象的尝试都会抛出异常。

可转移对象通常用于共享一次只能安全地暴露给单个JavaScript线程的资源。例如,ArrayBuffer是一个可转移的对象,它拥有一块内存。当这样的缓冲区在线程之间传输时,相关的内存资源将从原始缓冲区中分离出来,并附加到新线程中创建的缓冲区对象上。原始线程中的缓冲区对象不再可用,因为它不再拥有内存资源。

在使用structuredClone()创建对象的深度拷贝时也可能使用Transferring 。克隆操作之后,转移的资源将被移动,而不是复制到克隆对象中。

用于传输对象资源的机制取决于对象本身。例如,当在线程之间传输ArrayBuffer时,它所指向的内存资源实际上是在上下文之间以快速有效的零复制操作移动的。其他对象可以通过复制相关资源然后从旧上下文中删除来传输。

并不是所有的对象都是可转移的。下面提供了可转移对象的列表。

在线程之间传输对象

下面的代码演示了将消息从主线程发送到web worker线程时传输是如何工作的。Uint8Array在工作中被复制(复制),而它的缓冲区被转移。传输后,从主线程读取或写入uInt8Array的任何尝试都会抛出,但您仍然可以检查byteLength以确认它现在为零。

// Create an 8MB "file" and fill it. 8MB = 1024 * 1024 * 8 B
const uInt8Array = new Uint8Array(1024 * 1024 * 8).map((v, i) => i);
console.log(uInt8Array.byteLength); // 8388608

// Transfer the underlying buffer to a worker
worker.postMessage(uInt8Array, [uInt8Array.buffer]);
console.log(uInt8Array.byteLength); // 0

注意:类型化数组,如Int32ArrayUint8Array,是可序列化的,但不可转移。然而,它们的底层缓冲区是ArrayBuffer,这是一个可转移的对象。我们可以在data参数发送uInt8Array.buffer。而不是传输数组中的uInt8Array

克隆操作期间的转移

下面的代码显示了structuredClone()操作,其中底层缓冲区从原始对象复制到克隆对象。

const original = new Uint8Array(1024);
const clone = structuredClone(original);
console.log(original.byteLength); // 1024
console.log(clone.byteLength); // 1024

original[0] = 1;
console.log(clone[0]); // 0

// Transferring the Uint8Array would throw an exception as it is not a transferable object
// const transferred = structuredClone(original, {transfer: [original]});

// We can transfer Uint8Array.buffer.
const transferred = structuredClone(original, { transfer: [original.buffer] });
console.log(transferred.byteLength); // 1024
console.log(transferred[0]); // 1

// After transferring Uint8Array.buffer cannot be used.
console.log(original.byteLength); // 0

Supported objects

注意:可转移对象在Web IDL文件中被标记为属性[Transferable]

2、接口

2.1 DedicatedWorkerGlobalScope

可以通过self关键字访问DedicatedWorkerGlobalScope对象(Worker全局作用域)。JavaScript Reference中列出了一些额外的全局函数、命名空间对象和构造函数,它们通常不与worker全局作用域关联,但在它上可用。参见:Functions available to workers.。
在这里插入图片描述

2.2 ServiceWorker

2.3 SharedWorker

2.4 SharedWorkerGlobalScope

2.5 Worker

Web Workers API 的Worker接口代表了一个可以通过脚本创建的后台任务,它可以将消息发送回它的创建者。

通过调用Worker("path/to/worker/script")构造函数来创建 worker。

Workers 可以自己产生新的Workers ,只要这些Workers 被托管在与父页相同的origin。

并不是所有的接口和函数都对 Worker中 的脚本可用。Workers 可以使用XMLHttpRequest进行网络通信,但是它的responseXMLchannel属性总是为null。(fetch也是可用的,没有这样的限制。)

在这里插入图片描述

构造函数

Worker()

创建一个专用(dedicated)的web worker,执行指定的URL处的脚本。这也适用于 Blob URLs。该脚本必须遵守同源策略。

注意:浏览器制造商对于数据URL是否同源存在分歧。虽然Firefox 10及以后的版本接受数据url,但并非所有其他浏览器都是如此。

new Worker(aURL)
new Worker(aURL, options)
  • aURL
    一个字符串,表示工作线程将要执行的脚本的URL。它必须遵守同源策略。

  • options 可选
    一个对象,其中包含可在创建对象实例时设置的选项属性。可用的属性如下:

    • type
      指定要创建的工作线程类型的字符串。取值为classicmodule。如果未指定,则使用的默认值为classic

    • credentials
      指定工作线程使用的凭据类型的字符串。该值可以是omitsame-origininclude。如果没有指定,或者如果type是classic,则默认使用omit (不需要凭据)。

    • name
      一个字符串,指定用于表示工作器范围的DedicatedWorkerGlobalScope的标识名,主要用于调试目的。

实例方法

  • Worker.postMessage()
    发送一个消息——由任何JavaScript对象组成——到worker的内部作用域。

Worker postMessage()方法委托给MessagePort postMessage()方法,该方法在事件循环中添加一个与接收MessagePort相对应的任务。

Worker可以使用DedicatedWorkerGlobalScope.postMessage方法将信息发送回生成它的线程。

postMessage(message)
postMessage(message, options)
postMessage(message, transfer)
  • message
    交付给worker的对象;这将在交付给DedicatedWorkerGlobalScope.message_event 事件的data 字段中。这可以是由结构化克隆算法处理的任何值或JavaScript对象,其中包括循环引用。
    如果没有提供消息参数,解析器将抛出SyntaxError。如果要传递给worker的数据不重要,则可以显式传递nullundefined

  • options 可选
    一个可选对象,它包含一个transfer 字段,该字段包含一组要传输其所有权的可传输对象。如果对象的所有权被转移,它将在发送它的上下文中变得不可用,并且只对发送它的 worker 可用。

  • transfer 可选
    可转移对象的可选数组,用于转移其所有权。如果对象的所有权被转移,它将在发送它的上下文中变得不可用,并且只对发送它的worker 可用。
    可转移对象是类的实例,如ArrayBuffer, MessagePort或ImageBitmap对象可以被转移。null不是可接受的transfer值。

注意: postMessage()一次只能发送一个对象。如上所示,如果你想传递多个值,你可以发送一个数组。

  • Worker.terminate()
    立即终止 worker。这不会让worker完成它的操作;它立刻停止了。ServiceWorker实例不支持此方法。

事件

  • error
    在工作线程中发生错误时触发。

  • message
    当worker的父进程收到来自该worker的消息时触发。

  • messageerror
    当Worker对象接收到无法反序列化的消息时触发。

  • rejectionhandled
    每次Promise被拒绝时触发,不管是否有处理程序来捕获拒绝。

  • unhandledrejection
    当Promise拒绝而没有处理程序捕获拒绝时触发。

Example

下面的代码片段使用Worker()构造函数创建一个Worker对象,然后使用该Worker对象:

const myWorker = new Worker("/worker.js");
const first = document.querySelector("input#number1");
const second = document.querySelector("input#number2");

first.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

有关完整示例,请参阅我们的 Basic dedicated worker example

2.6 WorkerGlobalScope

Web Workers API的WorkerGlobalScope接口是一个表示任何worker的作用域的接口。Workers 没有浏览器上下文;这个范围包含通常由Window对象传递的信息——在本例中是事件处理程序、控制台或相关的WorkerNavigator对象。每个WorkerGlobalScope都有自己的事件循环。

这个接口通常被每个worker类型特例化:dedicated worker的专用 DedicatedWorkerGlobalScope , shared worker的共享SharedWorkerGlobalScope, ServiceWorker的ServiceWorkerGlobalScope。self属性返回每个上下文的专用范围。

在这里插入图片描述

Example

你不能在代码中直接访问WorkerGlobalScope;然而,它的属性和方法是由更具体的全局作用域继承的,比如DedicatedWorkerGlobalScopeSharedWorkerGlobalScope。例如,你可以将另一个脚本导入到worker中,并使用以下两行打印出worker作用域的导航器对象的内容:

importScripts("foo.js");
console.log(navigator);

2.7 WorkerLocation

WorkerLocation接口定义了Worker执行的脚本的绝对位置。这样的对象为每个worker初始化,并通过WorkerGlobalScope可用。通过调用self.location获得的Location属性。

2.8 WorkerNavigator

WorkerNavigator接口表示允许从 Worker 访问的Navigator接口的一个子集。这样的对象为每个Worker初始化,并通过self.navigator属性可用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1076602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XPS测试仪器-科学指南针

在做 X 射线光电子能谱(XPS)测试时&#xff0c;科学指南针检测平台工作人员在与很多同学沟通中了解到&#xff0c;好多同学仅仅是通过文献或者师兄师姐的推荐对XPS测试有了解&#xff0c;但是对于其测试仪器还属于小白阶段&#xff0c;针对此&#xff0c;科学指南针检测平台团队…

ant design form数组修改 关联展示

根据form 数组项修改关联其他选项 如图&#xff0c;在项目开发中&#xff0c;每个form中有多个产品&#xff0c;提货方式不同&#xff0c;有一个需要邮寄展示收货地址&#xff0c;否则不用展示 // An highlighted block <Card title"产品信息" bordered{false}&g…

VulnHub narak

一、信息收集 1.nmap扫描开发端口 2.扫描目录 利用dirb扫描目录 3.发现 /webdav目录 访问 WebDAV 基于 HTTP 协议的通信协议&#xff0c;在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法&#xff0c;使应用程序可对Web Server直接读写&#xff0c;并支持写文件锁…

vue3源码解析

vue3源码解析与前端网络安全 VUE 3 拓展 vue3 对比 vue2 响应式数据 vue2 的响应式数据是通过 Object.defineProperty 进行数据劫持&#xff0c;其存在一些缺点&#xff1a; 必须要预知劫持的 key 是什么&#xff0c;并不能很好的监听到对象属性的添加、删除&#xff1b;初…

家政服务行业怎么做微信小程序开发

随着科技的不断发展&#xff0c;微信小程序已经成为了人们生活中不可或缺的一部分。在家政服务领域&#xff0c;微信小程序也发挥出了重要的作用。本文将探讨家政服务在微信小程序上可以实现的功能。 一、展示家政服务信息 微信小程序可以作为一个展示家政服务的平台&#xff…

XML外部实体注入攻击XXE

xml是扩展性标记语言&#xff0c;来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义&#xff08;可选&#xff09;、文档元素&#xff0c;一般无法直接打开&#xff0c;可以选择用excl或记事本打…

虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序

虚拟桌宠模拟器&#xff1a;VPet-Simulator&#xff0c;一个开源的桌宠软件, 可以内置到任何WPF应用程序 虚拟桌宠模拟器 一个开源的桌宠软件, 可以内置到任何WPF应用程序 获取虚拟桌宠模拟器 OnSteam(免费) 或 通过[Nuget]内置到你的WPF应用程序 1.虚拟桌宠模拟器 详细介绍 …

2023 10月2日 至 10 月8日学习总结

学了半天 想了还是需要进行个总结 1.做的题目 NSSCTF [BJDCTF 2020]easy_md5 md5实现sql-CSDN博客 [网鼎杯 2020 白虎组]PicDown python反弹shell proc/self目录的信息_双层小牛堡的博客-CSDN博客 [CISCN2019 华北赛区 Day1 Web5]CyberPunk 二次报错注入_双层小牛堡的博客-…

XPS表征(工作原理与特点)-科学指南针

在做 X 射线光电子能谱(XPS)测试时&#xff0c;科学指南针检测平台工作人员在与很多同学沟通中了解到&#xff0c;好多同学仅仅是通过文献或者师兄师姐的推荐对XPS有了解&#xff0c;但是对于XPS测试原理还属于小白阶段&#xff0c;针对此&#xff0c;科学指南针检测平台团队组…

Laya3.0 入门教程

点击play箭头 点击右边的开发者工具 就会弹出 chrome的调试窗口 然后定位到你自己的ts文件 直接在ts里断点即可 不需要js文件 如何自动生成代码&#xff1f; 比如你打开一个新项目 里面显示的是当前场景 只需要点击 UI运行时 右边的框就可以了 他会自动弹窗提示你 创建一个文…

iNet Network Scanner for Mac,轻松管理网络

iNet Network Scanner for Mac是一款强大的网络扫描工具&#xff0c;能够帮助你轻松管理和监控网络设备。 无论你是个人用户还是企业管理员&#xff0c;iNet Network Scanner都能为你提供全面而方便的网络管理体验。它可以快速扫描并识别局域网中的所有设备&#xff0c;包括电…

竞赛选题 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…

主机加固,防勒索病毒

​近年来&#xff0c;计算机以及互联网应用在中国得到普及和发展&#xff0c;已经深入到社会每个角落&#xff0c;政府&#xff0c;经济&#xff0c;军事&#xff0c;社会&#xff0c;文化和人们生活等各方面都越来越依赖于计算机和网络&#xff0c;电子政务&#xff0c;无纸办…

Flutter的Platform介绍-跨平台开发,如何根据不同平台创建不同UI和行为

文章目录 Flutter跨平台概念介绍跨平台开发平台相关性Platform ChannelPlatform-specific UIPlatform Widgets 如何判断当前是什么平台实例 Platform 类介绍获取当前平台的名称检查当前平台其他属性 利用flutter设计跨Android和IOS平台应用的技巧1. 遵循平台的设计准则2. 使用平…

Numpy Notes

np.linalg.norm() Matrix or vector norm return one of eight different matrix norms, or one of an infinite number of vector norms (described below), depending on the value of the ord parameter. np.linalg.norm() 用于求范数linalg : linear(线性) algebra(代数…

修改ubuntu服务器fs文件最大打开数

起因 在对项目进行压测的时候&#xff0c;请求异常 java.net.SocketException: socket closed&#xff0c;查看nginx代理服务器的日志。tail -f -n500 /var/log/nginx/error.log 显示 文件打开数太多socket() failed (24: Too many open files) while connecting to upstream …

新手小白教程之 圈X-QuantumultX i茅台自动预约教程

注意 本教程需要提前准备好BoxJS&#xff0c;QX最新版。 脚本作者onz3v 学习交流频道 https://pd.qq.com/s/2v3a5vkmj 第一步 配置QX 我们使用编辑配置文件&#xff0c;来配置脚本。 打开QX&#xff0c;点击左下角配置文件图标。 在rewrite_local输入以下代码 https://a…

基于小波神经网络的网络流量预测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022A 3.部分核心程序 ........................................................... %% 总流量数据 input(:,1)dat…

Hive - 检查分区 partition 是否存在

目录 一.引言 二.检查最新分区 三.检查任意分区 四.总结 一.引言 国庆期间任务因为某个 hive 表分区未成功创建&#xff0c;导致后续任务异常&#xff0c;为此也是苦逼的 6 点起床修复 bug。发生异常对应表的正常分区如下图所示&#xff0c;为 dt、hour 双分区: 为了保证后…

c++视觉处理---cv::Sobel()`算子

cv::Sobel()算子 cv::Sobel()是OpenCV库中的函数之一&#xff0c;用于计算图像的Sobel梯度。Sobel梯度是一种常用的图像处理技术&#xff0c;用于检测图像中的边缘和轮廓。 以下是cv::Sobel()函数的一般用法和参数&#xff1a; void cv::Sobel(cv::InputArray src, //…