JavaScript

JavaScript 知识量:26 - 101 - 483

19.1 原子操作><

SharedArrayBuffer- 19.1.1 -

SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于ArrayBuffer对象,它们都可以用来在共享内存(shared memory)上创建视图。与ArrayBuffer不同的是,SharedArrayBuffer不能被分离。可以使用 SharedArrayBuffer 对象来创建共享内存的视图,允许多个线程同时访问和修改同一块内存区域。

SharedArrayBuffer 的大小在创建时确定,并且不能改变。它提供了一种共享内存的方式,使得多个线程可以相互协作和通信。通过 Atomics 对象提供的一组静态方法,可以对 SharedArrayBuffer 对象进行原子操作,确保多线程环境下的数据安全性。

需要注意的是,由于 SharedArrayBuffer 的实现可能因浏览器和操作系统而异,因此在使用时需要谨慎处理兼容性和安全性问题。

原子操作基础- 19.1.2 -

Atomics对象提供了一种在全局上下文中执行原子操作的方式。这些操作在多线程环境中非常重要,因为它们可以确保数据的一致性和安全性。Atomics对象包含一组静态方法,可以在TypedArray实例(SharedArrayBuffer的引用)上执行原子操作。

以下是Atomics对象的一些常用方法:

  • Atomics.load(typedArray, index): 从给定的索引位置加载值,并返回该值。这个操作是线程安全的,可以确保在加载值时不会被其他线程干扰。

  • Atomics.store(typedArray, index, value): 将给定的值存储到给定的索引位置。这个操作是线程安全的,可以确保在存储值时不会被其他线程干扰。

  • Atomics.add(typedArray, index, value): 将给定的值添加到给定索引位置的值。这个操作是原子性的,可以确保在添加值时不会被其他线程干扰。

  • Atomics.sub(typedArray, index, value): 从给定索引位置的值中减去给定的值。这个操作是原子性的,可以确保在执行减法操作时不会被其他线程干扰。

  • Atomics.and(typedArray, index, value): 将给定索引位置的值与给定的值进行按位与操作,并将结果存储回给定索引位置的值。这个操作是原子性的,可以确保在执行按位与操作时不会被其他线程干扰。

  • Atomics.or(typedArray, index, value): 将给定索引位置的值与给定的值进行按位或操作,并将结果存储回给定索引位置的值。这个操作是原子性的,可以确保在执行按位或操作时不会被其他线程干扰。

  • Atomics.xor(typedArray, index, value): 将给定索引位置的值与给定的值进行按位异或操作,并将结果存储回给定索引位置的值。这个操作是原子性的,可以确保在执行按位异或操作时不会被其他线程干扰。

  • Atomics.exchange(typedArray, index, value): 用给定的值替换给定索引位置的值,并返回替换前的值。这个操作是原子性的,可以确保在执行交换操作时不会被其他线程干扰。

  • Atomics.compareExchange(typedArray, index, expectedValue, newValue): 如果给定索引位置的值等于expectedValue,则用newValue替换该值,并返回替换前的值;否则,返回false。这个操作是原子性的,可以确保在执行比较交换操作时不会被其他线程干扰。

这些方法都接受一个SharedArrayBuffer实例作为第一个参数,因为它引用了共享内存缓冲区。通过使用这些方法,多个线程可以安全地访问和修改共享内存中的数据,而不会出现数据竞争或不一致的问题。

跨文档消息- 19.1.3 -

跨文档消息传递(Cross-Document Messaging,简称XDM)是一种允许在两个不同的Web文档(或执行上下文)之间进行通信的Web API。这种通信可以在不同的浏览器窗口、标签页、Web Worker 或 Service Worker之间进行。

在XDM中,消息发送方(也称为发送窗口或源)和消息接收方(也称为目标窗口或目标)是两个完全独立的执行上下文,它们可能具有不同的全球对象(window对象),运行在不同的线程上,甚至可能来自不同的源。尽管如此,XDM 提供了一种安全、简单的机制,使它们能够通过消息传递进行通信。

XDM 使用 postMessage 方法和 message 事件进行通信。postMessage 方法允许在一个执行上下文中安全地发送消息到另一个上下文,而 message 事件则在接收到消息时在目标上下文中触发。以下是一个简单的XDM示例:

在发送窗口中:

// 创建一个消息对象  
var message = { text: "Hello, world!" };  
  
// 找到目标窗口的 `window` 对象  
var targetWindow = window.open('http://example.com');  
  
// 使用 `postMessage` 方法发送消息  
targetWindow.postMessage(message, '*');

在接收窗口中:

// 监听 `message` 事件  
window.addEventListener('message', function(event) {  
    // 当接收到消息时处理消息内容  
    console.log("Received message: " + event.data);  
});

在这个例子中,创建了一个包含文本的简单消息对象,然后使用 postMessage 方法将其发送到新打开的窗口。在接收窗口中,使用 addEventListener 来监听 message 事件,并在接收到消息时打印出消息内容。

值得注意的是,为了防止潜在的安全问题(例如,一个网页通过发送消息来操纵另一个网页的内容),Web Workers 和 Service Workers 在处理 postMessage 消息时有一个限制:它们不能接收非法的全局对象。这意味着,例如,它们不能接收包含函数或正则表达式的消息。这是为了防止恶意脚本通过传递函数或正则表达式来操纵接收窗口的全局对象。