مفاهیم پایه نخ‌ها و مشکلات آن

تار و پود یک سیستم‌عامل کارآمد

نخ1، دنباله‌ای از دستورات است که اجرا می‌شود. برنامه‌ای که بیشتر از یک دنباله از دستورات را برای اجرا دنبال می‌کند، چندنخی2 ‌است. به‌عنوان مثال، اگر یک فایل بزرگ را بخواهیم بخوانیم و همزمان، کاربر قادر باشد که با کلیک بر روی گزینه کنسل در هر زمانی عملیات را متوقف کند، توسعه‌دهنده کد با افزودن یک نخ جدید، عملیات ورود داده را به‌طور جداگانه انجام می‌دهد و با پیاده‌سازی چند نخ به‌جای یک نخ، برنامه هنگام خواندن فایل، قفل نمی‌کند. ‌ ‌
کد خبر: ۲۴۰۷۲۰

سیستم عامل این چند نخی بودن را با مکانیزمی به‌نام تقسیم زمانی3‌ ‌پیاده می‌کند. تقسیم زمانی همواره رخ می‌دهد، حتی اگر از چندین پردازنده در یک سیستم استفاده شود، تعداد نخ‌ها به‌حدی خواهد رسید که باز هم تقسیم زمانی رخ خواهد داد. تقسیم زمانی در واقع عمل گرفتن کنترل اجرای عملیات از یک نخ (دنباله‌ای از دستورات) و انتقال آن به یک نخ دیگر با سرعتی است که به‌نظر برسد هر دو نخ‌ها به‌طور موازی انجام می‌شوند. ‌ ‌

می‌توانیم تمام این روند را به خط فیبرنوری تشبیه کنیم. به‌طوری که فیبرنوری کار پردازشگر را انجام می‌دهد و مکالماتی که میان این‌دو انجام می‌شود، نقش نخ را دارد. یک فیبرنوری تک‌حالته4‌ ‌می‌تواند در لحظه، فقط یک سیگنال را منتقل کند، اما بسیاری از مردم می‌توانند با استفاده از همین یک خط، نسبت به برقراری مکالمه همزمان اقدام کنند. این موضوع به‌این خاطر است که فیبرنوری به‌حد کافی برای تغییر از یک سیگنال به سیگنال دیگر سریع است و به‌همین علت مکالمات بدون قطعی ادامه خواهند یافت. نخ‌ها هم در یک پروسس چندنخی به‌همین ترتیب اجرا خواهند شد.

از آن‌جایی که یک نخ معمولا منتظر رویدادهای مختلفی چون عملیات ورودی™خروجی، می‌ماند، تغییر از یک نخ به نخ دیگر، باعث اجرای موثرتری می‌شود، چرا که پردازنده بیکار نمی‌ماند تا عملیات نخ انجام شود. هر چند، این انتقال خود باعث ایجاد سرآیندی می‌شود که در صورت وجود نخ‌های زیاد، سرآیند حاصل نسبت به سود میزان بیشتری خواهد شد و سیستم کندتر عمل خواهد کرد. ‌ ‌

حتی کسانی که با برنامه‌نویسی آشنایی کمی دارند نیز، به اصطلاح چندنخی برخورده‌اند و همواره از پیچیدگی آن چیزهایی را شنیده‌اند. اما امروزه، و با وجود بسترهای نرم‌افزاری حاضر، سعی شده است که پیاده‌سازی چندنخی، تا حد امکان ساده انجام شود و برنامه‌نویسی چندنخی ساده‌تر شده است. هر چند که هنوز پیچیدگی‌های خاصی برای نوشتن یک برنامه با تکنیک چندنخی باقی مانده است و نتیجه این‌که نوشتن یک برنامه که چندین نخ داشته باشد و از بن‌بست‌ها جلوگیری کند و احتمال وقوع شرایط رقابتی را به‌حداقل برساند، هنوز مهارت خاصی می‌طلبد. ‌ ‌

تجزیه ناپذیری

بیایید کدی را تصور کنیم که مقداری پول را از یک حساب بانکی منتقل می‌کند. در نگاه اول، کد بایستی بررسی کند که آیا مبلغ کافی در حساب موجود است یا خیر؛ اگر مبلغ کافی موجود است، انتقال انجام شود. اگر بعد از بررسی مبلغ موجود در حساب، اجرا به نخی منتقل شود که مبلغ را از حساب برداشت کند، در این صورت ممکن است انتقالی انجام شود که معتبر نیست. مشخص است که راه‌حل، کنترل حساب بانکی است، به‌گونه‌ای که فقط یک نخ بتواند تا پایان عملیات خود به آن دسترسی داشته باشد. عملیات تجزیه ناپذیر ‌(Atomic)‌ عملیاتی است که در آن یا تمام مراحل به‌طور کامل طی می‌شود، یا سیستم به حالت قبل از اجرای آن عملیات برمی‌گردد. انتقال حساب در سیستم بانکی تجزیه‌ناپذیر است به این خاطر که ممکن است یک نخ دیگر، تجزیه‌ناپذیری عملیات را به‌خطر بیاندازد. ‌ ‌تشخیص و پیاده‌سازی تجزیه‌ناپذیری یکی از بزرگ‌ترین پیچیدگی‌های برنامه‌نویسی چندنخی است. ‌ ‌

این پیچیدگی با فهمیدن این موضوع که، بیشتر زبان‌های برنامه‌نویسی، دستورات تجزیه‌ناپذیر ندارند، افزایش می‌یابد. مثلا دستور++  ‌count‌، یک دستور ساده در زبان ‌C‌ است، اما در مرحله کامپایل به چندین دستور تبدیل می‌شود:

1– پردازنده داده موجود در ‌count‌ را می‌خواند.

2– پردازنده عدد جدید را محاسبه می‌کند.

3– پردازنده مقدار جدید را داخل ‌count‌ می‌ریزد (که حتی ممکن است این ریزدستور هم تجزیه‌ناپذیر نباشد.)

پس از این‌که داده مورد دسترسی قرار گرفت و پیش از آن‌که مقدار جدید محاسبه شود، نخ دیگری عدد اصلی را تغییر می‌دهد و شرایط بحرانی برای دسترسی به محتویات متغیر ‌count‌ رخ می‌دهد و دست آخر، مقدار ‌count‌ غلط محاسبه می‌شود.

بن‌بست

برای جلوگیری از چنین موضوعی، زبان‌های برنامه‌نویسی از قابلیتی پشتیبانی می‌کنند که قسمتی از کد را، فقط برای تعداد معینی نخ قابل دسترسی می‌کند (که معمولا یک خواهد بود.) هر چند که اگر ترتیب قفل کردن نخ‌ها، صحیح نباشد، امکان وقوع بن‌بست هم وجود دارد و در این‌صورت برنامه هنگ می‌کند. ‌ ‌

عدم قطعیت

مشکل کدی که تجزیه‌ناپذیر نیست و منجر به بن‌بست می‌شود، کاملا به پردازنده و شیوه پیاده‌سازی چندنخی آن بستگی دارد. نتیجه این می‌شود که اجرای برنامه، دچار عدم قطعیت خواهد شد و از آن‌جا که تشخیص این‌که چطور یک فرآیند چندنخی، به‌درستی یا نادرستی کار می‌کند، نیازمند چرخه‌های پردازنده و بررسی احتمالات و شانس است، در این صورت رفع عیب یا پیشگیری از وقوع بن‌بست‌ها در شرایط آزمایشگاهی در عمل غیرممکن خواهد بود و نیازمند اجرا در زمان‌های طولانی است. ‌ ‌

منبع ‌ ‌

Beginning Multithread Applications

‌2003 Using C#, Wrox,‌

پی‌نوشت‌ها

 Thread.1‌

Multithread.2‌

 Time Slicing.3‌

 Single Mode.4

newsQrCode
ارسال نظرات در انتظار بررسی: ۰ انتشار یافته: ۰

نیازمندی ها