Atomics.pause()
Baseline
2025
Newly available
Since April 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Phương thức tĩnh Atomics.pause() cung cấp một primitive chờ vi mô (micro-wait) gợi ý cho CPU rằng thread gọi đang xoay vòng trong khi chờ truy cập vào một tài nguyên chia sẻ. Điều này cho phép hệ thống giảm tài nguyên được phân bổ cho nhân (core) hoặc thread (như điện năng) mà không từ bỏ thread hiện tại.
pause() không có hành vi quan sát được ngoài thời gian. Hành vi chính xác phụ thuộc vào kiến trúc CPU và hệ điều hành. Ví dụ, trên Intel x86, nó có thể là lệnh pause theo tài liệu tối ưu hóa của Intel. Nó có thể là no-op trên một số nền tảng nhất định.
Cú pháp
Atomics.pause()
Atomics.pause(durationHint)
Tham số
durationHintOptional-
Một số nguyên mà implementation có thể sử dụng để xác định thời gian chờ. Với giá trị
n + 1, một implementation chờ ít nhất lâu bằng thời gian nó chờ cho giá trịn. Con số chính xác không có ý nghĩa vật lý. Có thể có một giới hạn trên nội bộ về thời gian tối đa bị tạm dừng trong khoảng hàng chục đến hàng trăm nanosecond. Điều này có thể được sử dụng để thực hiện chiến lược backoff bằng cách tăngdurationHintđược truyền vào. Không có đảm bảo rằng một implementation sẽ sử dụng gợi ý này.
Giá trị trả về
Không có (undefined).
Ngoại lệ
TypeError-
Ném ra nếu
durationHintkhông phải là số nguyên hoặcundefined.
Ví dụ
Lưu ý rằng các ví dụ này không thể chạy trực tiếp từ console hoặc một trang web tùy ý, vì SharedArrayBuffer không được định nghĩa trừ khi các yêu cầu bảo mật của nó được đáp ứng.
Sử dụng Atomics.pause()
Việc gọi Atomics.wait() hoặc Atomics.waitAsync() để chờ truy cập vào bộ nhớ chia sẻ khiến thread bị lên lịch ra khỏi nhân và sau đó trở lại sau khi chờ. Điều này hiệu quả trong thời gian tranh chấp cao, khi truy cập vào bộ nhớ chia sẻ có thể mất một thời gian. Khi tranh chấp thấp, thường hiệu quả hơn khi thăm dò khóa mà không từ bỏ thread: cách tiếp cận này được gọi là busy waiting hay spinlocking. Phương thức pause() cho phép bạn spinlock hiệu quả hơn trong khi chờ, bằng cách cung cấp gợi ý cho CPU về những gì thread đang làm, và do đó nhu cầu tài nguyên thấp của nó.
Để phục vụ cả hai điều kiện, một cách tiếp cận phổ biến là đầu tiên spinlock với hy vọng tranh chấp thấp, sau đó chờ nếu khóa không được giành sau một thời gian ngắn. Nếu chúng ta đã giành được khóa thông qua spinlocking, thì lời gọi wait() sẽ là no-op.
Ví dụ dưới đây cho thấy cách tiếp cận này có thể được sử dụng với Atomics.pause() và Atomics.wait().
Warning: Việc sử dụng spinlocking trên main thread không được khuyến nghị, vì nó sẽ đóng băng toàn bộ trang. Nói chung, trừ khi được thiết kế rất cẩn thận, spinlock thực ra có thể không hiệu quả hơn một lần chờ thông thường.
// Imagine another thread also has access to this shared memory
const sab = new SharedArrayBuffer(1024);
const i32 = new Int32Array(sab);
// Fast path: spin the CPU for a short while
let spin = 0;
do {
if (Atomics.compareExchange(i32, 0, 0, 1) === 0) {
break;
}
Atomics.pause();
spin++;
} while (spin < 10);
// Slow path: wait for the lock
// This can only be called in a worker thread,
// because the main thread cannot be blocked
Atomics.wait(i32, 0, 1);
Chiến lược backoff
Tham số durationHint có thể được sử dụng để thực hiện chiến lược backoff. Ví dụ, một thread có thể bắt đầu với một gợi ý nhỏ và tăng nó theo cấp số nhân trong mỗi lần lặp. Điều này tốt hơn việc gọi pause() nhiều lần vì trong code chưa được JIT, bản thân các lời gọi hàm có chi phí cao.
Note:
Các implementation thực ra có thể không sử dụng durationHint chút nào và luôn chờ trong thời gian cố định.
// Exponential backoff
for (let hint = 1; hint < 1000; hint *= 2) {
Atomics.pause(hint);
}
// Linear backoff
for (let hint = 1; hint < 100; hint++) {
Atomics.pause(hint);
}
Thông số kỹ thuật
| Thông số kỹ thuật |
|---|
| Atomics.pause> # Atomics.pause> |