Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重学js —— 结构化数据之Atomics对象 #125

Open
lizhongzhen11 opened this issue Jul 1, 2020 · 1 comment
Open

重学js —— 结构化数据之Atomics对象 #125

lizhongzhen11 opened this issue Jul 1, 2020 · 1 comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN

Comments

@lizhongzhen11
Copy link
Owner

lizhongzhen11 commented Jul 1, 2020

Atomics 对象

用来对 SharedArrayBuffer 对象进行原子操作。

  • MDN
  • 即固有对象 %Atomics%
  • 全局对象 "Atomics" 属性的初始值
  • 属于 普通对象
  • [[Prototype]] 内置插槽,值为 %Object.prototype%
  • 没有 [[Construct]] 内置方法;不能做构造器
  • 没有 [[Call]] 内置方法;不能被调用
  • Math 对象一样,所有的属性和方法都是静态的!

多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。(阻塞?

共享内存通信的规则由 内存模型 提供

Atomics.add ( typedArray, index, value )

  1. 定义 type类型化数组表 中对应 typedArray.[[TypedArrayName]] 的元素类型值
  2. 定义 isLittleEndian周围代理代理记录[[LittleEndian]] 字段值
  3. 定义 add 为新的具有参数 (xBytes, yBytes)读写修改函数,该函数捕获 typeisLittleEndian,调用时自动执行以下步骤:
    1. 定义 xRawBytesToNumeric(type, xBytes, isLittleEndian)
    2. 定义 yRawBytesToNumeric(type, yBytes, isLittleEndian)
    3. 定义 Tx 的类型
    4. 定义 sumT::add(x, y) (可能是 Number::add ( x, y ),也可能是 BigInt::add( x, y )
    5. 定义 sumBytesNumericToRawBytes(type, sum, isLittleEndian)
    6. 断言:sumBytes, xBytes, 和 yBytes 有相同数量的元素
    7. 返回 sumBytes
  4. 返回 ? AtomicReadModifyWrite(typedArray, index, value, add)

Atomics.and ( typedArray, index, value )

  1. 定义 and 为新的具有参数 (xBytes, yBytes)读写修改函数,该函数不捕获任何东西,调用时自动执行以下步骤:
    1. 返回 ByteListBitwiseOp(&, xBytes, yBytes)
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, and)

Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )

  1. 定义 buffer? ValidateSharedIntegerTypedArray(typedArray)
  2. 定义 i? ValidateAtomicAccess(typedArray, index)
  3. 定义 arrayTypeNametypedArray.[[TypedArrayName]]
  4. 如果 typedArray.[[ContentType]]BigInt
    1. 定义 expected? ToBigInt(expectedValue)
    2. 定义 replacement? ToBigInt(replacementValue)
  5. 否则,
    1. 定义 expected? ToInteger(expectedValue)
    2. 定义 replacement? ToInteger(replacementValue)
  6. 定义 elementType类型化数组表 中对应 arrayTypeName 的元素类型值
  7. 定义 isLittleEndian周围代理代理记录[[LittleEndian]] 字段值
  8. 定义 expectedBytesNumericToRawBytes(elementType, expected, isLittleEndian)
  9. 定义 elementSize类型化数组表 中对应 arrayTypeName 的元素大小值
  10. 定义 offsettypedArray.[[ByteOffset]]
  11. 定义 indexedPosition(i × elementSize) + offset
  12. 定义 compareExchange 为新的具有参数 (oldBytes, newBytes)读写修改函数,该函数捕获 expectedBytes,调用时自动执行以下步骤:
    1. 如果 ByteListEqual(oldBytes, expectedBytes) 为 true,返回 newBytes
    2. 返回 oldBytes
  13. 返回 GetModifySetValueInBuffer(buffer, indexedPosition, elementType, replacement, compareExchange)

Atomics.exchange ( typedArray, index, value )

  1. 定义 second 为新的具有 参数 (oldBytes, newBytes)读写修改函数,该函数不捕获任何东西,调用时自动执行以下步骤:
    1. 返回 newBytes
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, second)

Atomics.isLockFree ( size )

  1. 定义 n? ToInteger(size)
  2. 定义 AR周围代理代理记录
  3. 如果 n = 1,返回 AR.[[IsLockFree1]]
  4. 如果 n = 2,返回 AR.[[IsLockFree2]]
  5. 如果 n = 4,返回 true
  6. 如果 n = 8,返回 AR.[[IsLockFree8]]
  7. 返回 false

Atomics.load ( typedArray, index )

  1. 返回 ? AtomicLoad(typedArray, index)

Atomics.or ( typedArray, index, value )

  1. 定义 or 为新的具有参数 (xBytes, yBytes)读写修改函数,该函数不捕获任何东西,调用时自动执行以下步骤:
    1. 返回 ByteListBitwiseOp(|, xBytes, yBytes)
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, or)

Atomics.store ( typedArray, index, value )

  1. 定义 buffer?ValidateSharedIntegerTypedArray(typedArray)
  2. 定义 i?ValidateAtomicAccess(typedArray, index)
  3. 定义 arrayTypeNametypedArray.[[TypedArrayName]]
  4. 如果 arrayTypeName"BigUint64Array""BigInt64Array",定义 v?ToBigInt(value)
  5. 否则,定义 v?ToInteger(value)
  6. 定义 elementSize类型化数组表 中对应 arrayTypeName 的元素大小值
  7. 定义 elementType类型化数组表 中对应 arrayTypeName 的元素类型值
  8. 定义 offsettypedArray.[[ByteOffset]]
  9. 定义 indexedPosition(i × elementSize) + offset
  10. 执行 SetValueInBuffer(buffer, indexedPosition, elementType, v, true, SeqCst)
  11. 返回 v

Atomics.sub ( typedArray, index, value )

  1. 定义 type类型化数组表 中对应 typedArray.[[TypedArrayName]] 的元素类型值
  2. 定义 isLittleEndian周围代理代理记录[[LittleEndian]] 字段值
  3. 定义 subtract 为具有参数 (xBytes, yBytes)读写修改函数,该函数捕获 typeisLittleEndian,调用时自动执行以下步骤:
    1. 定义 xRawBytesToNumeric(type, xBytes, isLittleEndian)
    2. 定义 yRawBytesToNumeric(type, yBytes, isLittleEndian)
    3. 定义 Tx 的类型
    4. 定义 differenceT::subtract(x, y) (可能是 Number::subtract ( x, y ),也可能是 BigInt::subtract( x, y )
    5. 定义 differenceBytesNumericToRawBytes(type, difference, isLittleEndian)
    6. 断言:differenceBytesxBytesyBytes 有相同数量的元素
    7. 返回 differenceBytes
  4. 返回 ? AtomicReadModifyWrite(typedArray, index, value, subtract)

Atomics.wait ( typedArray, index, value, timeout )

  1. 定义 buffer? ValidateSharedIntegerTypedArray(typedArray, true)
  2. 定义 i? ValidateAtomicAccess(typedArray, index)
  3. 定义 arrayTypeNametypedArray.[[TypedArrayName]]
  4. 如果 arrayTypeName"BigInt64Array",定义 v? ToBigInt64(value)
  5. 否则,定义 v? ToInt32(value)
  6. 定义 q? ToNumber(timeout)
  7. 如果 qNaN,定义 t+∞,否则定义 tmax(q, 0)
  8. 定义 BAgentCanSuspend
  9. 如果 Bfalse,抛 TypeError 异常
  10. 定义 blockbuffer.[[ArrayBufferData]]
  11. 定义 offsettypedArray.[[ByteOffset]]
  12. 定义 elementSize类型化数组表 中对应 arrayTypeName 的元素大小值
  13. 定义 indexedPosition(i × elementSize) + offset
  14. 定义 WLGetWaiterList(block, indexedPosition)
  15. 执行 EnterCriticalSection(WL)
  16. 定义 w! AtomicLoad(typedArray, i)
  17. 如果 v != w
    1. 执行 LeaveCriticalSection(WL)
    2. 返回字符串 "not-equal"
  18. 定义 WAgentSignifier
  19. 执行 AddWaiter(WL, W)
  20. 定义 notifiedSuspend(WL, W, t)
  21. 如果 notifiedtrue
    1. 断言:W 不在 WL 服务列表中
  22. 否则,
    1. 执行 RemoveWaiter(WL, W)
  23. 执行 LeaveCriticalSection(WL)
  24. 如果 notifiedtrue,返回字符串 "ok"
  25. 返回字符串 "timed-out"

Atomics.notify ( typedArray, index, count )

Atomics.xor ( typedArray, index, value )

  1. 定义 xor 为新的具有参数 (xBytes, yBytes)读写修改函数,该函数不捕获任何东西,调用时自动执行以下步骤:
    1. 返回 ByteListBitwiseOp(^, xBytes, yBytes)
  2. 返回 ? AtomicReadModifyWrite(typedArray, index, value, xor)

注意

Atomics.wait 中示例代码不能直接在主线程执行(我做了修改),规范中也在调用 AgentCanSuspend 时明确提到了:

在某些环境中,挂起代理程序可能不合理。例如,在浏览器环境中,禁止挂起文档的主事件处理线程,但是同时仍然允许 workers 的事件处理线程挂起。

如果直接在浏览器控制台输入 MDN 给的代码会报错!需要用 Worker 开辟新的线程,在新的线程中使用 Atomics.wait 睡眠该线程。

永远不应该尝试睡眠主线程!

我在 codepen 上写了个例子,可以看看:https://codepen.io/lizhongzhen11/project/editor/AmzyaY# (记得打开f12看浏览器控制台输出,用谷歌,同事用的火狐打开报 SharedArrayBuffer 未定义

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN
Projects
None yet
Development

No branches or pull requests

2 participants