এমন একটি ফাংশন যা কিছু মান গ্রহণ করে এবং অন্য কিছু মান ফেরত দেয়, এবং ফাংশনের বাইরের কোনও কিছুকে বিরক্ত করে না, এর কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং তাই থ্রেড-নিরাপদ। আপনি যদি ফাংশনটি সম্পাদন করে বিদ্যুৎ ব্যবহারকে কীভাবে প্রভাবিত করে এর মতো বিষয়গুলি বিবেচনা করতে চান, তবে এটি একটি ভিন্ন সমস্যা।
আমি ধরে নিচ্ছি যে আপনি এমন একটি টুরিং-সম্পূর্ণ মেশিনের কথা উল্লেখ করছেন যা কিছু প্রকারের সু-সংজ্ঞায়িত প্রোগ্রামিং ভাষা কার্যকর করছে, যেখানে প্রয়োগের বিবরণ অপ্রাসঙ্গিক। অন্য কথায়, স্ট্যাকটি কী করছে তা বিবেচনা করা উচিত নয়, যদি আমি আমার প্রোগ্রামিংয়ের পছন্দের ভাষায় যে ফাংশনটি লিখছি তা যদি ভাষার সীমায় আবদ্ধতার গ্যারান্টি দিতে পারে। আমি যখন উচ্চ-স্তরের ভাষায় প্রোগ্রাম করি তখন আমি স্ট্যাকটি সম্পর্কে ভাবি না, বা আমারও করা উচিত নয়।
এটি কীভাবে কাজ করে তা বোঝানোর জন্য, আমি সি # তে কয়েকটি সহজ উদাহরণ সরবরাহ করতে যাচ্ছি। এই উদাহরণগুলি সত্য হওয়ার জন্য, আমাদের কয়েকটা অনুমান করতে হবে। প্রথমত, যে সংকলকটি ত্রুটি ছাড়াই সি # নির্দিষ্টকরণ অনুসরণ করে এবং দ্বিতীয়টি এটি সঠিক প্রোগ্রাম উত্পাদন করে।
ধরা যাক আমি একটি সাধারণ ফাংশন চাই যা একটি স্ট্রিং সংগ্রহ গ্রহণ করে এবং একটি স্ট্রিং দেয় যা কমা দ্বারা পৃথকীকরণে সংগ্রহের সমস্ত স্ট্রিংয়ের সংমিশ্রণ। সি # তে একটি সরল, নির্বাক বাস্তবায়ন এর মতো দেখতে পাওয়া যেতে পারে:
public string ConcatenateWithCommas(ImmutableList<string> list)
{
string result = string.Empty;
bool isFirst = false;
foreach (string s in list)
{
if (isFirst)
result += s;
else
result += ", " + s;
}
return result;
}
এই উদাহরণটি অপরিবর্তনীয়, প্রথম দিকের। আমি কীভাবে জানি? কারণ string
বস্তু অপরিবর্তনীয়। তবে বাস্তবায়ন আদর্শ নয়। result
অপরিবর্তনীয় কারণ , প্রতিবার লুপের মাধ্যমে একটি নতুন স্ট্রিং অবজেক্ট তৈরি করতে হবে, যা মূল বিষয়টিকে নির্দেশ করে result
points এটি গতিতে নেতিবাচকভাবে প্রভাব ফেলতে পারে এবং আবর্জনা সংগ্রহকারীকে চাপ দিতে পারে, যেহেতু এটি অতিরিক্ত সমস্ত স্ট্রিং পরিষ্কার করতে হয়।
এখন, আমি বলি যে আমি এটি করছি:
public string ConcatenateWithCommas(ImmutableList<string> list)
{
var result = new StringBuilder();
bool isFirst = false;
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
লক্ষ্য করুন আমি string
result
একটি পরিবর্তনীয় বস্তুর সাথে প্রতিস্থাপন করেছি StringBuilder
,। এটি প্রথম উদাহরণের চেয়ে অনেক দ্রুত, কারণ লুপের মাধ্যমে প্রতিবার একটি নতুন স্ট্রিং তৈরি হয় না। পরিবর্তে, স্ট্রিংবিল্ডার অবজেক্ট কেবল প্রতিটি স্ট্রিং থেকে অক্ষরের সংকলনে অক্ষর যুক্ত করে এবং শেষে পুরো জিনিসটি আউটপুট করে।
স্ট্রিংবিল্ডার পরিবর্তনযোগ্য হলেও এই ফাংশনটি কি অপরিবর্তনীয়?
হ্যাঁ, তাই কেন? প্রতিবার এই ফাংশনটি ডাকা হওয়ার কারণে , কেবলমাত্র সেই কলটির জন্যই একটি নতুন স্ট্রিংবিল্ডার তৈরি করা হয়। সুতরাং এখন আমাদের কাছে একটি খাঁটি ফাংশন রয়েছে যা থ্রেড-নিরাপদ তবে এতে পরিবর্তনীয় উপাদান রয়েছে।
তবে আমি যদি এটা করতাম?
public class Concatenate
{
private StringBuilder result = new StringBuilder();
bool isFirst = false;
public string ConcatenateWithCommas(ImmutableList<string> list)
{
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
}
এই পদ্ধতিটি কি থ্রেড-নিরাপদ? না, তা নয়। কেন? কারণ ক্লাসটি এখন এমন অবস্থা ধরে রেখেছে যেটির উপর আমার পদ্ধতি নির্ভর করে। একটি দৌড় শর্ত এখন পদ্ধতিতে উপস্থিত রয়েছে: একটি থ্রেড সংশোধন করতে পারে IsFirst
তবে অন্য থ্রেডটি প্রথম সঞ্চালন করতে পারে Append()
, সেক্ষেত্রে আমার স্ট্রিংয়ের শুরুতে এখন আমার কমা রয়েছে যা সেখানে থাকার কথা নয়।
আমি কেন এটি এটি করতে চাই? ঠিক আছে, আমি চাইব যে থ্রেডগুলি result
অর্ডারকে বিবেচনা না করেই আমার মধ্যে স্ট্রিংগুলি জমা করতে পারে বা থ্রেডগুলি যে ক্রমে আসে Maybe সম্ভবত এটি কোনও লগার, কে জানে?
যাইহোক, এটি ঠিক করার জন্য, আমি lock
পদ্ধতির অভ্যন্তরের চারপাশে একটি বিবৃতি রেখেছি ।
public class Concatenate
{
private StringBuilder result = new StringBuilder();
bool isFirst = false;
private static object locker = new object();
public string AppendWithCommas(ImmutableList<string> list)
{
lock (locker)
{
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
}
}
এখন এটি আবার থ্রেড-নিরাপদ।
আমার অপরিবর্তনীয় পদ্ধতিগুলি থ্রেড-নিরাপদ হতে ব্যর্থ হওয়ার একমাত্র উপায় হ'ল পদ্ধতিটি যদি কোনওভাবে তার বাস্তবায়নের অংশ ফাঁস করে। এটা কি ঘটতে পারে? সংকলকটি সঠিক এবং প্রোগ্রামটি সঠিক হলে নয়। আমি কি কখনও এই জাতীয় পদ্ধতিতে লক প্রয়োজন? না।
কীভাবে বাস্তবায়নের সম্ভাব্য পরিস্থিতিতে দৃশ্যে ফাঁস হতে পারে তার উদাহরণের জন্য, এখানে দেখুন ।
but everything has a side effect
- আহ, না এটা হয় না। এমন একটি ফাংশন যা কিছু মান গ্রহণ করে এবং অন্য কিছু মান ফেরত দেয়, এবং ফাংশনের বাইরের কোনও কিছুকে বিরক্ত করে না, এর কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং তাই থ্রেড-নিরাপদ। কম্পিউটার বিদ্যুৎ ব্যবহার করে তাতে কিছু যায় আসে না। আমরা চাইলে মেমোরি কোষগুলিকে আঘাত করা মহাজাগতিক রশ্মি সম্পর্কেও কথা বলতে পারি, তবে যুক্তিটিকে ব্যবহারিক করে তোলা যাক। আপনি যদি ফাংশনটি সঞ্চালনের উপায়টি কীভাবে বিদ্যুৎ খরচকে প্রভাবিত করে সে মতো বিষয়গুলি বিবেচনা করতে চান, এটি থ্রেডসেফ প্রোগ্রামিংয়ের চেয়ে আলাদা সমস্যা।