Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Shared memory and multithreading in Node.js - Timur Shemsedinov - JSFest'19

4,119 views

Published on

Introduction to multithreading concurrent programming in Node.js with worker_threads, SharedArrayBuffer and Atomics. Examples of Race condition, Deadlock, Livelock and Starvation, Critical sections and Synchronization. Combination of asynchronous and concurrent programming with synchronization primitives: Semaphore, Counting Semaphore, Mutex, Monitor, Shared/Exclusive Locks, Queue Locks with priority etc. Use cases for shared memory and multithreading with thread-safe classes, data structures and Promises. Current state of worker_threads in Node.js, known problems and workarounds.

Published in: Software
  • Was a little hesitant about using ⇒⇒⇒WRITE-MY-PAPER.net ⇐⇐⇐ at first, but am very happy that I did. The writer was able to write my paper by the deadline and it was very well written. So guys don’t hesitate to use it.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • There is a useful site for you that will help you to write a perfect and valuable essay and so on. Check out, please ⇒ www.HelpWriting.net ⇐
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • If u need a hand in making your writing assignments - visit ⇒ www.HelpWriting.net ⇐ for more detailed information.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Is there any video of the presentation?
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Shared memory and multithreading in Node.js - Timur Shemsedinov - JSFest'19

  1. 1. Timur Shemsedinov 5-6 APRIL Introduction to multithreading concurrent programming in Node.js with worker_threads, SharedArrayBuffer and Atomics Shared memory and multithreading in Node.js
  2. 2. Shared memory and multithreading in Node.js Process - Separate memory - Separate resources - Separate environment Process / Thread Thread - Shared memory space - Shared resources - Common environment Memory mapped files
  3. 3. Shared memory and multithreading in Node.js Node.js - child_process - cluster - worker_threads --experimental-worker - Atomics - SharedArrayBuffer Node.js 10.5 ... 11.7
  4. 4. process Shared memory and multithreading in Node.js process JavaScript thread V8 libuv node.js JavaScript Shared memory and Message passing thread V8 libuv node.js JavaScript thread V8 libuv node.js IPC
  5. 5. Shared memory and multithreading in Node.js Node.js: worker_threads Not supported: - process.abort() - process.chdir(name) - process.initgroups(...) - trace_events module - IPC from parent - process.setegid(id) - process.seteuid(id) - process.setgid(id) - process.setgroups(...) - process.setuid(id)
  6. 6. Shared memory and multithreading in Node.js Node.js: worker_threads Read-only in Worker threads: - process.env - process.title - process.umask([mask])
  7. 7. Shared memory and multithreading in Node.js Node.js: worker_threads Different behavior: - process.exit([code]) stops thread not process - process.memoryUsage() rss for entire process - Each thread has an independent async_hooks - Signals will not be delivered through process.on
  8. 8. Shared memory and multithreading in Node.js Node.js: worker_threads API const threads = require('worker_threads'); const { Worker, isMainThread } = threads; if (isMainThread) { const worker = new Worker(__filename, { workerData: {} }); } else { const { parentPort } = threads; }
  9. 9. Shared memory and multithreading in Node.js Node.js: MessagePort API worker.on('message', (...args) => {}); worker.on('error', err => {}); worker.on('exit', code => {}); worker.postMessage('Hello there!'); parentPort.postMessage('Hello there!'); parentPort.on('message', (...args) => {});
  10. 10. Shared memory and multithreading in Node.js class Point { constructor(buffer, offset) { this.data = new Int8Array(buffer, offset, 2); } get x() { return this.data[0]; } set x(value) { this.data[0] = value; } ... Wrap Shared Memory with OOP
  11. 11. Shared memory and multithreading in Node.js const buffer = new SharedArrayBuffer(64); const point = new Point(buffer, 4); point.x += 10; point.y = 7; const { x } = point; Wrap Shared Memory with OOP
  12. 12. Shared memory and multithreading in Node.js - Parallel Programming - Asynchronous Programming - Actor Model - Transactional Memory - Coroutines Concurrent Computing
  13. 13. Shared memory and multithreading in Node.js Parallel Programming - Race condition - Critical section - Deadlock - Livelock - Starvation
  14. 14. Shared memory and multithreading in Node.js Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array Atomics and SharedArrayBuffer
  15. 15. Shared memory and multithreading in Node.js prev = Atomics.add(array, index, value) prev = Atomics.sub(array, index, value) prev = Atomics.and(array, index, value) prev = Atomics.or(array, index, value) prev = Atomics.xor(array, index, value) ES2017 Atomics
  16. 16. Shared memory and multithreading in Node.js function add(array, index, value) { 1 const prev = array[index]; 2 const sum = prev + value; 3 array[index] = sum; 4 return prev; } Atomics.add(array, index, value)
  17. 17. Shared memory and multithreading in Node.js stored = Atomics.store(array, index, value) value = Atomics.load(array, index) prev = Atomics.exchange(array, index, value) prev = Atomics.compareExchange( array, index, expected, replacement ) ES2017 Atomics (CAS)
  18. 18. Shared memory and multithreading in Node.js woken = Atomics.notify(array, index, count) res = Atomics.wait(array, index, value, [timeout]) res <"ok" | "not-equal" | "timed-out"> array <Int32Array> ES2017 Atomics (notify/wait)
  19. 19. Shared memory and multithreading in Node.js Synchronization primitives - Semaphore - BinarySemaphore - CountingSemaphore - Condition variable - SpinLock - Mutex - TimedMutex - SharedMutex - RecursiveMutex - Monitor - Barrier
  20. 20. Shared memory and multithreading in Node.js - thread safe data structures - lock-free data structures - wait-free algorithms - conflict-free data structures Parallel Solutions
  21. 21. Shared memory and multithreading in Node.js class Mutex { constructor(shared, offset = 0) enter() leave() } https://github.com/HowProgrammingWorks/Mutex Mutex
  22. 22. Shared memory and multithreading in Node.js mutex.enter(); // do something // with shared resources // or data structures mutex.leave(); Mutex usage
  23. 23. Shared memory and multithreading in Node.js constructor(shared, offset = 0) { this.lock = new Int32Array(shared, offset, 1); this.owner = false; } const threads = require('worker_threads'); const { workerData } = threads; const mutex1 = new Mutex(workerData, offset); Mutex constructor
  24. 24. Shared memory and multithreading in Node.js enter() { let prev = Atomics.exchange(this.lock, 0, LOCKED); while (prev !== UNLOCKED) { Atomics.wait(this.lock, 0, LOCKED); prev = Atomics.exchange(this.lock, 0, LOCKED); } this.owner = true; } Example: 6-blocking.js Mutex.enter with Atomics.wait
  25. 25. Shared memory and multithreading in Node.js leave() { if (!this.owner) return; Atomics.store(this.lock, 0, UNLOCKED); Atomics.notify(this.lock, 0, 1); this.owner = false; } Mutex.leave with Atomics.notify
  26. 26. Shared memory and multithreading in Node.js mutex.enter(() => { // do something // with shared resources // or data structures mutex.leave(); }); Async Mutex usage
  27. 27. Shared memory and multithreading in Node.js await mutex.enter(); // do something // with shared resources // or data structures mutex.leave(); Async Mutex usage
  28. 28. Shared memory and multithreading in Node.js enter() { return new Promise(resolve => { while (true) { let prev = Atomics.exchange(this.lock, 0, LOCKED); if (prev === UNLOCKED) break; } this.owner = true; resolve(); }); } Spinlock
  29. 29. Shared memory and multithreading in Node.js enter() { return new Promise(resolve => { const tryEnter = () => { let prev = Atomics.exchange(this.lock, 0, LOCKED); if (prev === UNLOCKED) { this.owner = true; resolve(); } else { setTimeout(tryEnter, 0); } }; tryEnter(); }); } Spinlock with setTimeout
  30. 30. Shared memory and multithreading in Node.js constructor(messagePort, shared, offset = 0) { this.port = messagePort; this.lock = new Int32Array(shared, offset, 1); this.owner = false; this.trying = false; this.resolve = null; if (messagePort) { messagePort.on('message', kind => { if (kind === 'leave' && this.trying) this.tryEnter(); }); } Example: 8-async.js } Asynchronous Mutex
  31. 31. Shared memory and multithreading in Node.js enter() { return new Promise(resolve => { this.resolve = resolve; this.trying = true; this.tryEnter(); }); } Asynchronous Mutex.enter
  32. 32. Shared memory and multithreading in Node.js tryEnter() { if (!this.resolve) return; let prev = Atomics.exchange(this.lock, 0, LOCKED); if (prev === UNLOCKED) { this.owner = true; this.trying = false; this.resolve(); this.resolve = null; } } Asynchronous Mutex.tryEnter
  33. 33. Shared memory and multithreading in Node.js - Low-level structures e.g. Register, Counter, Buffer, Array, Lists... - Abstract structures e.g. Queue, Graph, Polyline, etc. - Subject-domain classes e.g. Sensors, Payment, Biometric data, etc. Thread safe data structures
  34. 34. Shared memory and multithreading in Node.js locks.request('resource', opt, async lock => { if (lock) { // critical section for `resource` // will be released after return } }); https://wicg.github.io/web-locks/ Web Locks API
  35. 35. Shared memory and multithreading in Node.js - https://github.com/nodejs/node/issues/22702 Open - https://github.com/nodejs/node/pull/22719 Closed Web Locks for Node.js
  36. 36. Shared memory and multithreading in Node.js - Web Locks requires memory + messaging - Multiple locks.request() calls requires queue - Mutex.queue: Array<Lock> // resource - Lock { name, mode, callback } // request - Need await locks.request() - Options: { mode, ifAvailable, steal, signal } Web Locks API Implementation
  37. 37. Shared memory and multithreading in Node.js locks.request('resource', lock => new Promise( (resolve, reject) => { // you can store or pass resolve and // reject here as callbacks } )); https://wicg.github.io/web-locks/ Web Locks: Promise or thenable
  38. 38. Shared memory and multithreading in Node.js const controller = new AbortController(); setTimeout(() => controller.abort(), 200); const { signal } = controller; locks.request('resource', { signal }, async lock => { // lock is held }).catch(err => { // err is AbortError }); Web Locks: Abort
  39. 39. Shared memory and multithreading in Node.js - Passing handles between workers - Native add-ons (with certain conditions) - Debug - Experimental https://github.com/nodejs/node/issues/22940 To be solved
  40. 40. Shared memory and multithreading in Node.js https://github.com/HowProgrammingWorks/Semaphore https://github.com/HowProgrammingWorks/Mutex https://github.com/metarhia/metasync https://wicg.github.io/web-locks https://nodejs.org/api/worker_threads.html https://developer.mozilla.org/en-US/docs/Web/ JavaScript/Reference/Global_Objects/Atomics Links
  41. 41. Shared memory and multithreading in Node.js https://github.com/tshemsedinov https://www.youtube.com/TimurShemsedinov timur.shemsedinov@gmail.com Thanks

×