1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-25 03:02:21 +00:00

docs(ArrayBuffer): edit ArrayBuffer

This commit is contained in:
ruanyf 2017-08-01 07:02:24 +08:00
parent c850187bd7
commit 11f7f679c7

View File

@ -10,7 +10,7 @@
**1`ArrayBuffer`对象**:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。 **1`ArrayBuffer`对象**:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。
**2TypedArray视图**共包括9种类型的视图比如`Uint8Array`无符号8位整数数组视图, `Int16Array`16位整数数组视图, `Float32Array`32位浮点数数组视图等等。 **2`TypedArray`视图**共包括9种类型的视图比如`Uint8Array`无符号8位整数数组视图, `Int16Array`16位整数数组视图, `Float32Array`32位浮点数数组视图等等。
**3`DataView`视图**:可以自定义复合格式的视图,比如第一个字节是 Uint8无符号8位整数、第二、三个字节是 Int1616位整数、第四个字节开始是 Float3232位浮点数等等此外还可以自定义字节序。 **3`DataView`视图**:可以自定义复合格式的视图,比如第一个字节是 Uint8无符号8位整数、第二、三个字节是 Int1616位整数、第四个字节开始是 Float3232位浮点数等等此外还可以自定义字节序。
@ -1041,7 +1041,7 @@ onmessage = function (ev) {
共享内存也可以在 Worker 线程创建,发给主线程。 共享内存也可以在 Worker 线程创建,发给主线程。
`SharedArrayBuffer``SharedArray`一样,本身是无法读写,必须在上面建立视图,然后通过视图读写。 `SharedArrayBuffer``ArrayBuffer`一样,本身是无法读写,必须在上面建立视图,然后通过视图读写。
```javascript ```javascript
// 分配 10 万个 32 位整数占据的内存空间 // 分配 10 万个 32 位整数占据的内存空间
@ -1075,7 +1075,7 @@ onmessage = function (ev) {
## Atomics 对象 ## Atomics 对象
多线程共享内存最大的问题就是如何防止两个线程同时修改某个地址或者说当一个线程修改共享内存以后必须有一个机制让其他线程同步。SharedArrayBuffer API 提供`Atomics`对象,保证所有共享内存的操作都是“原子性”的,并且可以在所有程内同步。 多线程共享内存最大的问题就是如何防止两个线程同时修改某个地址或者说当一个线程修改共享内存以后必须有一个机制让其他线程同步。SharedArrayBuffer API 提供`Atomics`对象,保证所有共享内存的操作都是“原子性”的,并且可以在所有线程内同步。
什么叫“原子性操作”呢?现代编程语言中,一条普通的命令被编译器处理以后,会变成多条机器指令。如果是单线程运行,这是没有问题的;多线程环境并且共享内存时,就会出问题,因为这一组机器指令的运行期间,可能会插入其他线程的指令,从而导致运行结果出错。请看下面的例子。 什么叫“原子性操作”呢?现代编程语言中,一条普通的命令被编译器处理以后,会变成多条机器指令。如果是单线程运行,这是没有问题的;多线程环境并且共享内存时,就会出问题,因为这一组机器指令的运行期间,可能会插入其他线程的指令,从而导致运行结果出错。请看下面的例子。
@ -1092,7 +1092,7 @@ console.log(ia[42]);
// 191 // 191
``` ```
上面代码中主线程的原始顺序是先对42号位置赋值再对37号位置赋值。但是编译器和 CPU 为了优化,可能会改变这两个操作的执行顺序因为它们之间互不依赖先对37号位置赋值再对42号位置赋值。而执行到一半的时候Worker 线程可能就会来读取数据,导致打印出`123456``191` 上面代码中主线程的原始顺序是先对42号位置赋值再对37号位置赋值。但是编译器和 CPU 为了优化可能会改变这两个操作的执行顺序因为它们之间互不依赖先对37号位置赋值再对42号位置赋值。而执行到一半的时候Worker 线程可能就会来读取数据,导致打印出`123456``191`
下面是另一个例子。 下面是另一个例子。
@ -1112,7 +1112,7 @@ Atomics.add(ia, 112, 1); // 正确
上面代码中Worker 线程直接改写共享内存`ia[112]++`是不正确的。因为这行语句会被编译成多条机器指令,这些指令之间无法保证不会插入其他进程的指令。请设想如果两个线程同时`ia[112]++`,很可能它们得到的结果都是不正确的。 上面代码中Worker 线程直接改写共享内存`ia[112]++`是不正确的。因为这行语句会被编译成多条机器指令,这些指令之间无法保证不会插入其他进程的指令。请设想如果两个线程同时`ia[112]++`,很可能它们得到的结果都是不正确的。
`Atomics`对象就是为了解决这个问题而提出,它可以保证一个操作所对应的多条机器指令,一定是作为一个整体运行的,中间不会被打断。也就是说,它所涉及的操作都可以看作是原子性的单操作,这可以避免线程竞争,提高多线程共享内存时的操作安全。所以,`ia[112]++`要改写成`Atomics.add(ia, 112, 1)` `Atomics`对象就是为了解决这个问题而提出,它可以保证一个操作所对应的多条机器指令,一定是作为一个整体运行的,中间不会被打断。也就是说,它所涉及的操作都可以看作是原子性的单操作,这可以避免线程竞争,提高多线程共享内存时的操作安全。所以,`ia[112]++`要改写成`Atomics.add(ia, 112, 1)`
`Atomics`对象提供多种方法。 `Atomics`对象提供多种方法。