বাইন্ডারের থ্রেডিং মডেলটি স্থানীয় ফাংশন কলগুলিকে সহজ করার জন্য ডিজাইন করা হয়েছে যদিও সেই কলগুলি দূরবর্তী প্রক্রিয়াতে হতে পারে। বিশেষভাবে, একটি নোড হোস্ট করা যে কোনো প্রক্রিয়ার অবশ্যই সেই প্রক্রিয়ায় হোস্ট করা নোডগুলিতে লেনদেন পরিচালনা করতে এক বা একাধিক বাইন্ডার থ্রেডের একটি পুল থাকতে হবে।
সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস লেনদেন
বাইন্ডার সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস লেনদেন সমর্থন করে। নিম্নলিখিত বিভাগগুলি ব্যাখ্যা করে যে কীভাবে প্রতিটি লেনদেনের ধরন নির্বাহ করা হয়।
সিঙ্ক্রোনাস লেনদেন
সিঙ্ক্রোনাস লেনদেনগুলি নোডে কার্যকর না হওয়া পর্যন্ত ব্লক করে এবং সেই লেনদেনের জন্য কলকারীর দ্বারা একটি উত্তর পাওয়া যায়। নিম্নলিখিত চিত্রটি দেখায় কিভাবে একটি সিঙ্ক্রোনাস লেনদেন সম্পাদিত হয়:
চিত্র 1. সিঙ্ক্রোনাস লেনদেন।
একটি সিঙ্ক্রোনাস লেনদেন চালানোর জন্য, বাইন্ডার নিম্নলিখিতগুলি করে:
- টার্গেট থ্রেডপুলের (T2 এবং T3) থ্রেডগুলি ইনকামিং কাজের জন্য অপেক্ষা করার জন্য কার্নেল ড্রাইভারকে কল করে।
- কার্নেল একটি নতুন লেনদেন গ্রহণ করে এবং লেনদেন পরিচালনা করার লক্ষ্যে একটি থ্রেড (T2) জাগিয়ে তোলে।
- কলিং থ্রেড (T1) ব্লক করে এবং উত্তরের জন্য অপেক্ষা করে।
- লক্ষ্য প্রক্রিয়াটি লেনদেন সম্পাদন করে এবং একটি উত্তর প্রদান করে।
- টার্গেট প্রসেসের (T2) থ্রেডটি নতুন কাজের জন্য অপেক্ষা করার জন্য কার্নেল ড্রাইভারকে আবার কল করে।
অ্যাসিঙ্ক্রোনাস লেনদেন
অ্যাসিঙ্ক্রোনাস লেনদেন সম্পূর্ণ হওয়ার জন্য ব্লক করে না; লেনদেনটি কার্নেলে পাস করার সাথে সাথেই কলিং থ্রেডটি আনব্লক হয়ে যায়। নিম্নলিখিত চিত্রটি দেখায় কিভাবে একটি অ্যাসিঙ্ক্রোনাস লেনদেন সম্পাদিত হয়:
চিত্র 2. অ্যাসিঙ্ক্রোনাস লেনদেন।
- টার্গেট থ্রেডপুলের (T2 এবং T3) থ্রেডগুলি ইনকামিং কাজের জন্য অপেক্ষা করার জন্য কার্নেল ড্রাইভারকে কল করে।
- কার্নেল একটি নতুন লেনদেন গ্রহণ করে এবং লেনদেন পরিচালনা করার লক্ষ্যে একটি থ্রেড (T2) জাগিয়ে তোলে।
- কলিং থ্রেড (T1) সঞ্চালন অব্যাহত থাকে।
- লক্ষ্য প্রক্রিয়াটি লেনদেন সম্পাদন করে এবং একটি উত্তর প্রদান করে।
- টার্গেট প্রসেসের (T2) থ্রেডটি নতুন কাজের জন্য অপেক্ষা করার জন্য কার্নেল ড্রাইভারকে আবার কল করে।
একটি সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস ফাংশন সনাক্ত করুন
AIDL ফাইলে oneway
হিসাবে চিহ্নিত ফাংশনগুলি অ্যাসিঙ্ক্রোনাস। যেমন:
oneway void someCall();
যদি একটি ফাংশন oneway
হিসাবে চিহ্নিত না হয় তবে এটি একটি সিঙ্ক্রোনাস ফাংশন, এমনকি যদি ফাংশনটি void
ফেরত দেয়।
অ্যাসিঙ্ক্রোনাস লেনদেনের ক্রমিকীকরণ
বাইন্ডার যেকোনো একক নোড থেকে অ্যাসিঙ্ক্রোনাস লেনদেনকে সিরিয়ালাইজ করে। নিম্নলিখিত চিত্রটি দেখায় কিভাবে বাইন্ডার অ্যাসিঙ্ক্রোনাস লেনদেনগুলিকে সিরিয়ালাইজ করে:
চিত্র 3. অ্যাসিঙ্ক্রোনাস লেনদেনের সিরিয়ালাইজেশন।
- টার্গেট থ্রেডপুলের (B1 এবং B2) থ্রেডগুলি ইনকামিং কাজের জন্য অপেক্ষা করার জন্য কার্নেল ড্রাইভারকে কল করে।
- একই নোডে (N1) দুটি লেনদেন (T1 এবং T2) কার্নেলে পাঠানো হয়।
- কার্নেল একটি নতুন লেনদেন গ্রহণ করে এবং যেহেতু তারা একই নোড (N1) থেকে এসেছে, সেগুলিকে সিরিয়ালাইজ করে।
- একটি ভিন্ন নোডের (N2) আরেকটি লেনদেন কার্নেলে পাঠানো হয়।
- কার্নেল তৃতীয় লেনদেন গ্রহণ করে এবং লেনদেন পরিচালনা করার লক্ষ্যে একটি থ্রেড (B2) জাগিয়ে তোলে।
- লক্ষ্য প্রক্রিয়া প্রতিটি লেনদেন সম্পাদন করে এবং একটি উত্তর প্রদান করে।
নেস্টেড লেনদেন
সিঙ্ক্রোনাস লেনদেন নেস্ট করা যেতে পারে; একটি থ্রেড যা একটি লেনদেন পরিচালনা করছে একটি নতুন লেনদেন জারি করতে পারে। নেস্টেড লেনদেন একটি ভিন্ন প্রক্রিয়া হতে পারে, বা একই প্রক্রিয়া হতে পারে যেটি থেকে আপনি বর্তমান লেনদেন পেয়েছেন৷ এই আচরণ স্থানীয় ফাংশন কল অনুকরণ. উদাহরণস্বরূপ, ধরুন আপনার নেস্টেড ফাংশন সহ একটি ফাংশন আছে:
def outer_function(x):
def inner_function(y):
def inner_inner_function(z):
যদি এগুলি স্থানীয় কল হয়, তবে সেগুলি একই থ্রেডে কার্যকর করা হয়। বিশেষত, যদি inner_function
এর কলারও নোড হোস্ট করার প্রক্রিয়া হয়ে থাকে যা inner_inner_function
প্রয়োগ করে, তাহলে inner_inner_function
এ কল একই থ্রেডে কার্যকর করা হয়।
নিচের চিত্রটি দেখায় কিভাবে বাইন্ডার নেস্টেড লেনদেন পরিচালনা করে:
চিত্র 4. নেস্টেড লেনদেন।
- থ্রেড A1 অনুরোধ করে চলমান
foo()
। - এই অনুরোধের অংশ হিসাবে, থ্রেড B1
bar()
চালায় যা A একই থ্রেড A1-এ চলে।
নিম্নলিখিত চিত্রটি থ্রেড এক্সিকিউশন দেখায় যদি bar()
প্রয়োগকারী নোডটি একটি ভিন্ন প্রক্রিয়ায় থাকে:
চিত্র 5. বিভিন্ন প্রক্রিয়ায় নেস্টেড লেনদেন।
- থ্রেড A1 অনুরোধ করে চলমান
foo()
। - এই অনুরোধের অংশ হিসাবে, থ্রেড B1
bar()
চালায় যা অন্য থ্রেড C1 এ চলে।
নিচের চিত্রটি দেখায় কিভাবে থ্রেডটি লেনদেন চেইনের যেকোনো জায়গায় একই প্রক্রিয়াটিকে পুনরায় ব্যবহার করে:
চিত্র 6. একটি থ্রেড পুনরায় ব্যবহার করে নেস্টেড লেনদেন।
- প্রক্রিয়া A প্রক্রিয়া B-তে কল করে।
- প্রক্রিয়া B প্রক্রিয়া C-তে কল করে।
- প্রক্রিয়া C তারপর প্রক্রিয়া A-তে একটি কল করে এবং কার্নেল A1 প্রক্রিয়া A-তে পুনরায় ব্যবহার করে যা লেনদেন চেইনের অংশ।
অ্যাসিঙ্ক্রোনাস লেনদেনের জন্য, নেস্টিং একটি ভূমিকা পালন করে না; ক্লায়েন্ট একটি অ্যাসিঙ্ক্রোনাস লেনদেনের ফলাফলের জন্য অপেক্ষা করে না, তাই কোনও নেস্টিং নেই। যদি একটি অ্যাসিঙ্ক্রোনাস লেনদেনের হ্যান্ডলার সেই প্রক্রিয়ায় একটি কল করে যা সেই অ্যাসিঙ্ক্রোনাস লেনদেনটি জারি করেছে, সেই লেনদেনটি সেই প্রক্রিয়ার যেকোনো বিনামূল্যের থ্রেডে পরিচালনা করা যেতে পারে।
অচলাবস্থা এড়িয়ে চলুন
নিম্নলিখিত চিত্রটি একটি সাধারণ অচলাবস্থা দেখায়:
চিত্র 7. সাধারণ অচলাবস্থা।
- প্রক্রিয়া A মিউটেক্স এমএ নেয় এবং B প্রক্রিয়া করার জন্য একটি বাইন্ডার কল (T1) করে যা মিউটেক্স এমবি নেওয়ার চেষ্টা করে।
- একই সাথে, B প্রক্রিয়াটি মিউটেক্স এমবি নেয় এবং A প্রক্রিয়া করার জন্য একটি বাইন্ডার কল (T2) করে যা মিউটেক্স এমএ নেওয়ার চেষ্টা করে।
যদি এই লেনদেনগুলি ওভারল্যাপ হয়, প্রতিটি লেনদেন সম্ভাব্যভাবে তাদের প্রক্রিয়াতে একটি মিউটেক্স নিতে পারে যখন অন্য প্রক্রিয়াটি একটি মিউটেক্স প্রকাশের জন্য অপেক্ষা করে, ফলে একটি অচলাবস্থা দেখা দেয়।
বাইন্ডার ব্যবহার করার সময় অচলাবস্থা এড়াতে, বাইন্ডার কল করার সময় কোনও লক ধরে রাখবেন না।
লক অর্ডার নিয়ম এবং অচলাবস্থা
একটি একক এক্সিকিউশন এনভায়রনমেন্টের মধ্যে, অচলাবস্থা প্রায়ই একটি লক অর্ডার নিয়মের সাথে এড়ানো হয়। যাইহোক, প্রসেস এবং কোডবেসের মধ্যে কল করার সময়, বিশেষত কোড আপডেট হওয়ার সাথে সাথে, একটি অর্ডারিং নিয়ম বজায় রাখা এবং সমন্বয় করা অসম্ভব।
একক মিউটেক্স এবং ডেডলক
নেস্টেড লেনদেনের সাথে, প্রক্রিয়া B একটি মিউটেক্স ধরে প্রক্রিয়া A-তে সরাসরি একই থ্রেডে ফিরে যেতে পারে। অতএব, অপ্রত্যাশিত পুনরাবৃত্তির কারণে, একটি একক মিউটেক্সের সাথে একটি অচলাবস্থা পাওয়া এখনও সম্ভব।
সিঙ্ক্রোনাস কল এবং অচলাবস্থা
যদিও অ্যাসিঙ্ক্রোনাস বাইন্ডার কলগুলি সম্পূর্ণ হওয়ার জন্য ব্লক করে না, আপনার অ্যাসিঙ্ক্রোনাস কলগুলির জন্য একটি লক রাখা এড়ানো উচিত। যদি আপনি একটি লক ধরে রাখেন, যদি একটি ওয়ান-ওয়ে কল ঘটনাক্রমে একটি সিঙ্ক্রোনাস কলে পরিবর্তিত হয় তাহলে আপনি লকিং সমস্যার সম্মুখীন হতে পারেন।
একক বাইন্ডার থ্রেড এবং অচলাবস্থা
বাইন্ডারের লেনদেন মডেলটি পুনরায় প্রবেশের অনুমতি দেয়, তাই এমনকি যদি একটি প্রক্রিয়াতে একটি একক বাইন্ডার থ্রেড থাকে, তবুও আপনার লকিং প্রয়োজন। উদাহরণস্বরূপ, ধরুন আপনি একটি একক-থ্রেডেড প্রক্রিয়া A-তে একটি তালিকার উপর পুনরাবৃত্তি করছেন। তালিকার প্রতিটি আইটেমের জন্য, আপনি একটি বহির্গামী বাইন্ডার লেনদেন করেন। আপনি যে ফাংশনটিকে কল করছেন তার বাস্তবায়ন যদি A প্রক্রিয়ায় হোস্ট করা একটি নোডে একটি নতুন বাইন্ডার লেনদেন করে, সেই লেনদেনটি একই থ্রেডে পরিচালনা করা হয় যা তালিকাটি পুনরাবৃত্তি করছে। যদি সেই লেনদেনের বাস্তবায়ন একই তালিকাকে পরিবর্তন করে, আপনি যখন পরে তালিকার উপর পুনরাবৃত্তি চালিয়ে যান তখন আপনি সমস্যার সম্মুখীন হতে পারেন।
থ্রেডপুলের আকার কনফিগার করুন
যখন একটি পরিষেবার একাধিক ক্লায়েন্ট থাকে, থ্রেডপুলে আরও থ্রেড যোগ করা বিবাদ কমাতে পারে এবং সমান্তরালে আরও কল পরিবেশন করতে পারে। আপনি সঠিকভাবে সঙ্গতি মোকাবেলা করার পরে, আপনি আরও থ্রেড যোগ করতে পারেন। একটি সমস্যা যা আরও থ্রেড যোগ করার কারণে হতে পারে যে কিছু থ্রেড শান্ত কাজের চাপের সময় ব্যবহার করা যাবে না।
একটি কনফিগার করা সর্বোচ্চ না হওয়া পর্যন্ত থ্রেড অন-ডিমান্ড তৈরি করা হয় একটি বাইন্ডার থ্রেড তৈরি হওয়ার পরে, এটি হোস্টিং প্রক্রিয়া শেষ না হওয়া পর্যন্ত এটি জীবিত থাকে।
লিবিন্ডার লাইব্রেরিতে ডিফল্ট 15টি থ্রেড রয়েছে। এই মান পরিবর্তন করতে setThreadPoolMaxThreadCount
ব্যবহার করুন:
using ::android::ProcessState;
ProcessState::self()->setThreadPoolMaxThreadCount(size_t maxThreads);