Atomics ব্যবহার করে Thread-Safe কোড লেখা

Atomics এর বেস্ট প্র্যাকটিস - অ্যাটমিক্স (Atomics) - Web Development

227

Atomics JavaScript-এর একটি API যা shared memory এবং multi-threading পরিবেশে atomic operations ব্যবহার করে ডেটার সঠিকতা এবং thread safety নিশ্চিত করতে সাহায্য করে। মাল্টি-থ্রেডেড প্রোগ্রামিংয়ে, একাধিক থ্রেড একসাথে একই ডেটা অ্যাক্সেস করে, যার ফলে race condition বা data corruption হতে পারে। Atomics API থ্রেড-সেফ কোড লেখার জন্য ব্যবহৃত হয়, যা ডেটার একাধিক থ্রেডের অ্যাক্সেস নিয়ন্ত্রণ করে।

এখানে আমরা দেখব কীভাবে Atomics ব্যবহার করে thread-safe কোড লেখা যায়।


Thread-Safe কোড লেখার মৌলিক ধারণা

Thread-Safe কোডের মানে হলো এমন কোড যা একাধিক থ্রেড একই সময়ে চালানোর পরেও সঠিকভাবে কাজ করে, ডেটার অবস্থা নষ্ট না করে। মাল্টি-থ্রেডেড পরিবেশে, সিঙ্ক্রোনাইজেশন অপরিহার্য, যাতে কোনো থ্রেড অন্য থ্রেডের কাজকে প্রভাবিত না করে।

Atomics API ব্যবহার করলে আমরা atomic operations (যেমন, add, sub, compareAndSet) করতে পারি যা নিশ্চিত করে যে, একে অপরের হস্তক্ষেপ ছাড়া ডেটা পরিবর্তন হবে।


Atomics API এর মাধ্যমে Thread-Safe কোড লেখা

১. Shared Memory এবং Atomic Operations

Atomics API মূলত SharedArrayBuffer এবং TypedArray এর সাথে কাজ করে। এটি একাধিক থ্রেডের মধ্যে শেয়ার করা মেমোরিতে নিরাপদভাবে অ্যাক্সেস নিশ্চিত করে। একাধিক থ্রেড যদি একই ডেটা পরিবর্তন করতে চায়, তখন atomic operations নিশ্চিত করে যে অপারেশনটি indivisible (অবিভাজ্য) হবে, অর্থাৎ অপারেশনটি শেষ হওয়ার আগে অন্য কোনো থ্রেড সেই ডেটার সাথে কাজ করতে পারবে না।

২. Atomic Operations

এখানে কিছু সাধারণ atomic operations ব্যবহার করা হয়:

  • Atomics.add(typedArray, index, value) – একটি ভ্যালু যোগ করা।
  • Atomics.sub(typedArray, index, value) – একটি ভ্যালু বিয়োগ করা।
  • Atomics.load(typedArray, index) – নির্দিষ্ট ইনডেক্স থেকে ডেটা পড়া।
  • Atomics.store(typedArray, index, value) – নির্দিষ্ট ইনডেক্সে ডেটা সংরক্ষণ করা।
  • Atomics.compareExchange(typedArray, index, expectedValue, replacementValue) – যদি ডেটা নির্দিষ্ট মানের সমান হয়, তবে সেটি পরিবর্তন করা।

উদাহরণ: Thread-Safe কোড লেখা Atomics ব্যবহার করে

ধরা যাক, আমাদের একটি সিম্পল counter পরিবর্তন করতে হবে, যেখানে একাধিক থ্রেড একই সময়ে এই counter এর মান পরিবর্তন করবে। Atomics এর সাহায্যে, আমরা এটি thread-safe করতে পারি।

উদাহরণ ১: Atomic Counter

// Shared memory allocation
const sharedBuffer = new SharedArrayBuffer(1024);
const typedArray = new Int32Array(sharedBuffer);

// Atomic function to increment counter
function incrementCounter() {
    for (let i = 0; i < 1000; i++) {
        Atomics.add(typedArray, 0, 1);  // Increment the counter atomically
    }
}

// Create two workers to increment counter simultaneously
const worker1 = new Worker(() => incrementCounter());
const worker2 = new Worker(() => incrementCounter());

// Wait for workers to finish and then log the final counter value
setTimeout(() => {
    console.log('Final Counter Value: ', Atomics.load(typedArray, 0));  // Expected output: 2000
}, 1000);

ব্যাখ্যা:

  • এখানে দুটি workers তৈরি করা হয়েছে যা একযোগে counter ইনক্রিমেন্ট করবে।
  • Atomics.add ব্যবহার করে, প্রতিটি worker atomically typedArray[0] ইনডেক্সে মান যোগ করবে।
  • Atomics.load এর মাধ্যমে আমরা শেষের মানটি পড়ে দেখতে পারব।

এই কোডটি thread-safe, কারণ আমরা atomic অপারেশন ব্যবহার করেছি যা নিশ্চিত করে যে counter এর মান একযোগে পরিবর্তন হলে কোনো ভুল বা race condition হবে না।


উদাহরণ ২: Compare-and-Swap (CAS) with Atomics

এখানে আমরা Compare-and-Swap (CAS) কৌশল ব্যবহার করব, যেখানে একটি ভ্যালু কেবল তখনই পরিবর্তন হবে যদি এটি একটি নির্দিষ্ট মানের সমান হয়।

// Shared memory allocation
const sharedBuffer = new SharedArrayBuffer(1024);
const typedArray = new Int32Array(sharedBuffer);

// Atomic Compare and Swap function
function atomicCompareAndSwap() {
    let oldValue = Atomics.load(typedArray, 0);
    let success = Atomics.compareExchange(typedArray, 0, oldValue, oldValue + 1);
    
    // If the CAS operation was successful, print the new value
    if (success === oldValue) {
        console.log('CAS Successful, new value: ', oldValue + 1);
    } else {
        console.log('CAS Failed');
    }
}

// Perform CAS operation
atomicCompareAndSwap();  // Try updating counter atomically

ব্যাখ্যা:

  • এখানে, আমরা প্রথমে Atomics.load ব্যবহার করে ভ্যালু পড়ি এবং তারপর Atomics.compareExchange ব্যবহার করে সেই ভ্যালু পরিবর্তন করার চেষ্টা করি যদি এটি আগের মানের সমান হয়।
  • CAS নিশ্চিত করে যে, যদি কোনো থ্রেড ডেটার উপর কাজ করছে, অন্য থ্রেড তাকে পুনরায় আপডেট না করে একই ডেটার উপর কাজ করতে পারবে না।

Thread-Safe কোড লেখার গুরুত্বপূর্ণ কৌশল

  1. Atomic Operations ব্যবহার করা:
    • Atomic operations নিশ্চিত করে যে ডেটার পরিবর্তন একযোগে হয় এবং অন্য কোনো থ্রেড হস্তক্ষেপ করতে পারে না।
  2. Shared Memory ব্যবহারের সময় সতর্কতা:
    • Shared memory ব্যবহারে সতর্ক থাকতে হবে এবং নিশ্চিত করতে হবে যে একাধিক থ্রেড নিরাপদভাবে ডেটা অ্যাক্সেস করতে পারে।
  3. Compare and Swap (CAS) ব্যবহার করা:
    • CAS কৌশলটি thread-safe অপারেশন নিশ্চিত করতে ব্যবহৃত হয়, যা race condition প্রতিরোধ করে।
  4. সিঙ্ক্রোনাইজেশন নিশ্চিত করা:
    • মাল্টি-থ্রেডেড পরিবেশে Atomics.wait() এবং Atomics.notify() এর মাধ্যমে থ্রেডগুলোর মধ্যে সিঙ্ক্রোনাইজেশন নিশ্চিত করা যায়।
  5. Immutable Data Structures:
    • যতটা সম্ভব immutable ডেটা স্ট্রাকচার ব্যবহার করতে চেষ্টা করুন যাতে একাধিক থ্রেড একই ডেটার উপর কাজ না করে এবং side effects কম থাকে।

উপসংহার

Atomics API মাল্টি-থ্রেডেড প্রোগ্রামিংয়ে thread-safe কোড লেখার জন্য অত্যন্ত কার্যকরী একটি টুল। এটি atomic operations সরবরাহ করে যা নিশ্চিত করে যে একাধিক থ্রেড একই ডেটার উপর একযোগে কাজ করলেও ডেটা সঠিকভাবে পরিবর্তিত হবে। মাল্টি-থ্রেড পরিবেশে race condition, data corruption, এবং deadlock এড়াতে Atomics একটি শক্তিশালী পদ্ধতি।

Content added By
Promotion

Are you sure to start over?

Loading...