VUE3.0을 빠르게 시작하는 방법: Enter Learning
여러 컨텍스트가 SharedArrayBuffer에 액세스할 때 버퍼에서 동시에 작업이 수행되면 리소스 경합 문제가 발생할 수 있습니다. Atomics API를 사용하면 버퍼에서 한 번에 하나의 작업만 수행할 수 있도록 강제하여 여러 컨텍스트에서 SharedArrayBuffer를 안전하게 읽고 쓸 수 있습니다.
원자적 연산의 특성으로 인해 운영 체제나 컴퓨터 하드웨어가 일반적으로 자동으로 수행하는 최적화(예: 명령 재정렬)가 불가능합니다. 또한 원자 연산은 메모리에 동시에 액세스하는 것을 불가능하게 만듭니다. 부적절하게 사용하면 프로그램 실행 속도가 느려질 수 있습니다. 이러한 이유로 Atomics API의 원래 설계 의도는 최소한이지만 안정적인 기반으로 복잡한 다중 스레드 JavaScript 프로그램을 구축하는 것입니다. 원자 행동.
Atomics API는 내부 수정 작업을 수행하기 위한 간단한 방법 집합을 제공합니다. ECMA 사양에서 이러한 메서드는 AtomicReadModifyWrite 작업으로 정의됩니다. 내부적으로 이러한 메서드는 SharedArrayBuffer의 위치에서 값을 읽고, 산술 및 비트 연산을 수행하고, 마지막으로 결과를 동일한 위치에 씁니다. 이러한 작업의 원자적 특성은 위에 설명된 읽기, 수정 및 다시 쓰기 작업이 순서대로 실행되고 다른 스레드에 의해 중단되지 않음을 의미합니다.
//크기 1의 버퍼 생성 let sharedArrayBuffer = new SharedArrayBuffer(1); //버퍼를 기반으로 Unit8Arraylet 생성 typedArray = new Unit8Array(sharedArrayBuffer); //모든 ArrayBuffer는 0console.log(typedArray)로 초기화됩니다. //Unit8Array[0] //인덱스 0의 값에 10의 원자 추가를 수행합니다.Atomics.add(typedArray,0,10); //Unit8Array[10] //인덱스 0Atomics.sub(typedArray,0,10)의 값에 대해 10의 원자 빼기를 수행합니다. //Unit8Array[0]
브라우저의 JavaScript 컴파일러와 CPU 아키텍처 자체에는 프로그램 실행 효율성을 높이기 위해 명령을 재배열할 수 있는 권한이 있습니다. 일반적인 상황에서 JavaScript의 단일 스레드 환경은 언제든지 이 최적화를 수행할 수 있지만 다중 스레드의 명령 재배열은 리소스 경합으로 이어질 수 있으며 문제 해결이 매우 어렵습니다.
Atomics API는 두 가지 주요 방법으로 이 문제를 해결합니다.
서로에 대한 모든 원자 명령어의 순서는 절대 재배열되지 않습니다.
원자성 읽기 또는 쓰기를 사용하면 원자성 읽기 및 쓰기에 비해 모든 명령어의 순서가 변경되지 않습니다.
버퍼 값을 읽고 쓰는 것 외에도 Atomics.load() 및 Atomics.store()는 "코드 펜스"를 구축할 수도 있습니다. JavaScript 엔진은 비원자적 명령이 load() 및 store()를 기준으로 로컬로 재배열될 수 있도록 보장하지만 이러한 재배열은 원자적 읽기 및 쓰기의 경계를 위반하지 않습니다.
const sharedArrayBuffer = 새로운 SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //비원자 쓰기 수행 view[0] = 1; //비원자적 쓰기는 이 읽기 작업 전에 완료되도록 보장할 수 있으므로 1console.log(Atomics.load(view,0))는 확실히 여기에서 읽혀집니다. //1 //원자적 쓰기 수행 Atomics.store(view,0,2); //원자적 쓰기가 완료된 후 비원자적 읽기가 보장될 수 있으며 2console.log(view[0])는 여기에서 확실히 읽혀집니다. //2
연속적이고 중단 없이 먼저 읽고 쓰기를 보장하기 위해 Atomics API는 exchange() 및 CompareExchange()라는 두 가지 메서드를 제공합니다. Atomics.exchange()는 다른 스레드가 교환을 중단하지 않도록 보장하는 간단한 교환을 수행합니다.
const sharedArrayBuffer = 새로운 SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //인덱스 0에 10Atomics.store(view,0,10)을 씁니다. //인덱스 0에서 값을 읽고 인덱스 0에 5를 씁니다.console.log(Atomics.exchange(view,0,5)); //10 //인덱스 0에서 값을 읽습니다. console.log(Atomics.load(view,0)); //5
다중 스레드 프로그램에서 스레드는 마지막으로 값을 읽은 이후 다른 스레드가 값을 수정하지 않은 경우에만 공유 버퍼에 쓰기를 원할 수 있습니다. 값이 수정되지 않은 경우 이 스레드는 업데이트된 값을 안전하게 쓸 수 있습니다. 값이 수정된 경우 쓰기 작업을 수행하면 다른 스레드에서 계산된 값이 삭제됩니다. 이러한 종류의 작업을 위해 Atomics API는 Compare-Exchange() 메서드를 제공합니다. 이 메서드는 대상 인덱스의 값이 예상 값과 일치하는 경우에만 쓰기 작업을 수행합니다.
일종의 잠금 메커니즘이 없으면 멀티 스레드 프로그램은 복잡한 요구 사항을 지원할 수 없습니다. 이를 위해 Atomics API는 Linux Futex(빠른 사용자 공간 뮤텍스)를 모방하는 메서드를 제공합니다. 이러한 방법은 그 자체로는 매우 간단하지만 보다 복잡한 잠금 메커니즘의 기본 구성 요소 역할을 할 수 있습니다.
모든 원자성 Futex 작업은 Int32Array 뷰에서만 사용할 수 있으며 작업자 스레드 내에서만 사용할 수 있습니다.
크로스 문서 메시징(XDM(크로스 문서 메시징)이라고도 함)은 서로 다른 실행 컨텍스트(예: 서로 다른 작업자 스레드 또는 서로 다른 소스의 페이지) 간에 정보를 전송하는 기능입니다.
인코딩 API는 주로 문자열과 스테레오타입 배열 간의 변환에 사용됩니다.
파일 API는 여전히 양식의 파일 입력 필드를 기반으로 하지만 파일 정보에 직접 액세스할 수 있는 기능을 추가합니다. HTML5는 파일 입력 요소에 대한 DOM에 파일 컬렉션을 추가합니다. 사용자가 파일 필드에서 하나 이상의 파일을 선택하면 파일 컬렉션에는 선택한 파일을 나타내는 File 개체 집합이 포함됩니다. 각 File 개체에는 몇 가지 읽기 전용 속성이 있습니다.
FileReader 유형은 서버에서 데이터를 읽는 대신 파일 시스템에서 파일을 읽는 데 사용된다는 점을 제외하면 FileReader를 XMLHttpRequest와 유사하다고 생각할 수 있습니다. FileReader 유형은 파일 데이터를 읽는 여러 가지 방법을 제공합니다.
readAsText(file,encoding);//파일에서 일반 텍스트 콘텐츠를 읽고 결과 속성에 저장합니다.
readAsDataURL(file);//파일을 읽고 콘텐츠의 데이터 URI를 결과 속성에 저장합니다.
readAsBinaryString(file); //파일을 읽어서 각 문자의 바이너리 데이터를 결과 속성에 저장합니다.
readAsArrayBuffer(file); //파일을 읽어서 파일 내용을 결과 속성에 ArrayBuffer 형식으로 저장합니다.
의 동기 버전
입니다.FileReader 유형입니다.
경우에 따라 전체 파일 대신 파일의 일부를 읽어야 할 수도 있습니다. 이를 위해 File 객체는 Slice()라는 메서드를 제공합니다. Slice() 메소드는 시작 바이트와 Yaodu 영역의 바이트 수라는 두 개의 매개변수를 받습니다. 이 메소드는 실제로 File의 슈퍼클래스인 Blob의 인스턴스를 반환합니다.
Blob은 수정 불가능한 바이너리 데이터에 대한 JavaScript의 캡슐화 유형인 바이너리 대형 객체를 나타냅니다. 문자열, ArrayBuffers, ArrayBufferViews 및 기타 blob을 포함하는 배열을 사용하여 blob을 생성할 수 있습니다. Blob 생성자는 옵션 매개변수를 수신하고 그 안에 MIME 유형을 지정할 수 있습니다.
Streams API는 간단하지만 기본적인 문제를 해결하기 위해 탄생했습니다. 웹 애플리케이션은 큰 정보 블록 대신 정렬된 작은 정보 블록을 어떻게 소비합니까? 이 기능에는 두 가지 주요 애플리케이션 시나리오가 있습니다.
Streams API는 세 가지 스트림을 정의합니다.
읽기 가능한 스트림: 공용 인터페이스를 통해 데이터 블록을 읽을 수 있는 스트림입니다. 데이터는 기본 소스에서 내부적으로 스트림에 들어간 다음 소비자에 의해 처리됩니다.
쓰기 가능한 스트림: 일부 공용 인터페이스를 통해 데이터 블록을 쓸 수 있는 스트림입니다. 생산자(소비자)는 스트림에 데이터를 쓰고, 데이터는 내부적으로 기본 데이터 슬롯(싱크)으로 전송됩니다.
변환 스트림: 두 개의 스트림으로 구성되며 쓰기 가능한 스트림은 데이터를 수신하는 데 사용되고 읽기 가능한 스트림은 데이터를 출력하는 데 사용됩니다. 이 두 가지 스트림 품질 검사는 필요에 따라 스트림 콘텐츠를 검사하고 수정할 수 있는 변환기입니다.
웹 암호화 API는 JavaScript가 안전하고 일반적인 방식으로 암호화를 구현하는 방법을 표준화하는 암호화 도구 세트를 설명합니다. 이러한 도구에는 암호화 키 쌍 생성, 사용 및 적용, 정보 암호화 및 해독, 안정적으로 난수 생성 등이 포함됩니다.
많은 사람들이 난수를 생성해야 할 때 Math.random()
사용합니다. 이 방법은 브라우저에서 의사 난수 생성기(PRNG, PseudoRandom Number Generator)로 구현됩니다. 소위 유사(pseudo)란 실제로 무작위가 아닌 값을 생성하는 과정을 말합니다. PRNG에 의해 생성된 값은 무작위 특성만을 시뮬레이션합니다. 브라우저의 PRNG는 진정한 무작위 소스를 사용하지 않고 내부 상태에만 고정된 알고리즘을 적용합니다. Math.random()
이 호출될 때마다 이 내부 상태는 알고리즘에 의해 수정되고 결과는 새로운 난수로 변환됩니다. 예를 들어 V8 엔진은 xorshift128+
라는 알고리즘을 사용하여 이러한 수정을 수행합니다.
알고리즘 자체는 고정되어 있고 입력은 이전 상태뿐이므로 난수열도 결정됩니다. xorshift128+
128비트 내부 상태를 사용하며, 알고리즘은 모든 초기 상태가 반복되기 전에 2 128 -1 의사 난수 값을 생성하도록 설계되었습니다. 이런 종류의 루프를 순열 루프라고 하며, 이 루프의 길이를 주기라고 합니다. 공격자가 PRNG의 내부 상태를 안다면 이후에 생성되는 의사 난수 값을 예측할 수 있다는 것은 명백합니다. 개발자가 실수로 PRNG를 사용하여 암호화용 개인 키를 생성하는 경우 공격자는 PRNG의 이 기능을 사용하여 개인 키를 계산할 수 있습니다.
의사 난수 생성기는 주로 난수처럼 보이는 것을 빠르게 계산하는 데 사용되지만 암호화 알고리즘에는 적합하지 않습니다. 이 문제를 해결하기 위해 암호학적으로 안전한 의사 난수 생성기(CSPRNG, Cryptographically Secure PseudoRandom Number Generator)와 같이 엔트로피를 추가합니다. 예측할 수 없는 동작으로 하드웨어 시간 또는 기타 시스템 특성 테스트와 같은 입력은 비록 PRNG만큼 빠르지는 않지만 생성된 값은 예측하기가 더 어렵고 암호화에 사용될 수 있습니다.
웹 암호화 API는 crypto.getRandomValues()
통해 전역 Crypto
개체에서 액세스할 수 있는 CSPRNG를 도입합니다. 0과 1 사이의 부동 소수점 숫자를 반환하는 Math.random()
과 달리 getRandomValues()
매개 변수로 전달된 스테레오타입 배열에 임의의 값을 씁니다. 기본 버퍼가 임의의 비트로 채워지기 때문에 스테레오타입 배열의 클래스는 중요하지 않습니다.