Điều này có thể xảy ra trong trường hợp biến a
được truy cập bởi, giả sử 2 nhân viên web thông qua SharedArrayBuffer cũng như một số tập lệnh chính. Khả năng là thấp, nhưng nó có thể là khi mã được biên dịch sang mã máy, các công nhân trang web cập nhật các biến a
chỉ trong thời gian như vậy điều kiện a==1
, a==2
vàa==3
được thỏa mãn.
Đây có thể là một ví dụ về điều kiện chủng tộc trong môi trường đa luồng được cung cấp bởi các nhân viên web và SharedArrayBuffer trong JavaScript.
Đây là cách thực hiện cơ bản ở trên:
main.js
// Main Thread
const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let's use 2 workers
const sab = new SharedArrayBuffer(1)
modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)
worker.js
let array
Object.defineProperty(self, 'a', {
get() {
return array[0]
}
});
addEventListener('message', ({data}) => {
array = new Uint8Array(data)
let count = 0
do {
var res = a == 1 && a == 2 && a == 3
++count
} while(res == false) // just for clarity. !res is fine
console.log(`It happened after ${count} iterations`)
console.log('You should\'ve never seen this')
})
modifier.js
addEventListener('message' , ({data}) => {
setInterval( () => {
new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
})
})
Trên MacBook Air của tôi, nó xảy ra sau khoảng 10 tỷ lần lặp lại trong lần thử đầu tiên:
Lần thử thứ hai:
Như tôi đã nói, cơ hội sẽ thấp, nhưng nếu có đủ thời gian, nó sẽ đạt được điều kiện.
Mẹo: Nếu mất quá nhiều thời gian trên hệ thống của bạn. Chỉ thử a == 1 && a == 2
và thay đổi Math.random()*3
thành Math.random()*2
. Thêm nhiều hơn và nhiều hơn vào danh sách giảm cơ hội đánh.