هی هابر! من می خواهم توجه شما را به مجموعه ای از مقالات - ترجمه های یک ادبیات جالب به نظر من - OSTEP جلب کنم. این مطالب عمیقاً کار سیستمهای عامل یونیکس مانند را مورد بحث قرار میدهد، یعنی کار با فرآیندها، زمانبندیهای مختلف، حافظه و سایر اجزای مشابه که یک سیستمعامل مدرن را تشکیل میدهند. شما می توانید اصل تمام مواد را اینجا ببینید اینجا. لطفا توجه داشته باشید که ترجمه غیرحرفه ای (کاملا آزادانه) انجام شده است، اما امیدوارم معنی کلی را حفظ کرده باشم.
کارهای آزمایشگاهی در مورد این موضوع را می توان در اینجا یافت:
شما همچنین می توانید از کانال من دیدن کنید تلگرام =)
عملیات برنامه
وقتی یک برنامه در حال اجرا است چه اتفاقی می افتد؟ یک برنامه در حال اجرا یک کار ساده را انجام می دهد - دستورالعمل ها را اجرا می کند. در هر ثانیه، میلیونها و حتی احتمالاً میلیاردها دستورالعمل توسط پردازنده از RAM بازیابی میشود، به نوبه خود آنها را رمزگشایی میکند (مثلاً تشخیص میدهد که این دستورالعملها متعلق به چه نوع هستند) و آنها را اجرا میکند. این می تواند اضافه کردن دو عدد، دسترسی به حافظه، بررسی یک وضعیت، پرش به یک تابع و غیره باشد. پس از اجرای یک دستور، پردازنده به اجرای دستور دیگر ادامه می دهد. و به این ترتیب دستورات پس از دستور، تا پایان برنامه اجرا می شوند.
این مثال به طور طبیعی ساده در نظر گرفته می شود - در واقع، برای افزایش سرعت پردازنده، سخت افزار مدرن به شما امکان می دهد دستورالعمل ها را خارج از نوبت اجرا کنید، نتایج احتمالی را محاسبه کنید، دستورالعمل ها را به طور همزمان اجرا کنید و ترفندهای مشابه.
مدل محاسباتی فون نیومن
شکل ساده شده کار توصیف شده توسط ما شبیه مدل محاسباتی فون نیومن است. فون نیومن یکی از پیشگامان سیستم های کامپیوتری است، او همچنین یکی از نویسندگان نظریه بازی ها است.. در حالی که برنامه در حال اجرا است، مجموعه ای از رویدادهای دیگر رخ می دهد، بسیاری از فرآیندهای دیگر و منطق شخص ثالث کار می کنند، که هدف اصلی آنها ساده کردن راه اندازی، بهره برداری و نگهداری سیستم است.
مجموعهای از نرمافزارها وجود دارند که وظیفه اجرای آسان برنامهها را بر عهده دارند (یا حتی اجازه میدهند چندین برنامه همزمان اجرا شوند)، که به برنامهها اجازه میدهد حافظه مشابهی را به اشتراک بگذارند و با دستگاههای مختلف ارتباط برقرار کنند. چنین مجموعه ای از نرم افزارها (نرم افزارها) در اصل سیستم عامل نامیده می شوند و وظایف آن شامل نظارت بر عملکرد صحیح و کارآمد سیستم و همچنین اطمینان از مدیریت آسان سیستم است.
سیستم عامل
سیستم عامل که به اختصار OS نامیده می شود، مجموعه ای از برنامه های مرتبط با یکدیگر است که برای مدیریت منابع رایانه و سازماندهی تعامل کاربر با رایانه طراحی شده اند..
سیستم عامل در وهله اول کارایی خود را از طریق مهم ترین تکنیک - تکنیک به دست می آورد مجازی سازی. سیستم عامل با یک منبع فیزیکی (پردازنده، حافظه، دیسک و غیره) در تعامل است و آن را به شکلی کلی تر، قوی تر و استفاده آسان تر از خود تبدیل می کند. بنابراین، برای درک کلی، می توانید سیستم عامل را با یک ماشین مجازی به طور تقریبی مقایسه کنید.
برای اینکه کاربران بتوانند دستوراتی به سیستم عامل بدهند و در نتیجه از قابلیت های ماشین مجازی (مانند اجرای برنامه، تخصیص حافظه، دسترسی به فایل و غیره) استفاده کنند، سیستم عامل رابطی به نام API (رابط برنامه نویسی برنامه) و می توانید با آن تماس بگیرید (تماس بگیرید). یک سیستم عامل معمولی اجازه می دهد تا صدها تماس سیستمی برقرار شود.
در نهایت، از آنجایی که مجازیسازی به چندین برنامه اجازه میدهد تا اجرا شوند (در نتیجه CPU را به اشتراک میگذارند)، و به طور همزمان به دستورالعملها و دادههای آنها (در نتیجه به اشتراکگذاری حافظه) و دسترسی به دیسکها (در نتیجه اشتراکگذاری دستگاههای ورودی/خروجی) دسترسی داشته باشند، سیستم عامل نیز نامیده میشود. مدیر منابع. هر پردازنده، دیسک و حافظه منبعی از سیستم است، و بنابراین یکی از نقش های سیستم عامل، وظیفه مدیریت این منابع، انجام کارآمد، صادقانه یا برعکس، بسته به وظیفه ای که این سیستم عامل برای آن انجام می دهد، می شود. طراحی شده است.
مجازی سازی CPU
برنامه زیر را در نظر بگیرید:
(https://www.youtube.com/watch?v=zDwT5fUcki4)
هیچ عمل خاصی را انجام نمی دهد، در واقع، تنها کاری که انجام می دهد فراخوانی یک تابع است چرخش() که وظیفه آن چرخش در بررسی زمان و بازگشت پس از گذشت یک ثانیه است. بنابراین، رشته ای را که کاربر به عنوان آرگومان ارسال کرده است، به طور نامحدود تکرار می کند.
بیایید این برنامه را اجرا کنیم و کاراکتر A را به عنوان آرگومان به آن منتقل کنیم. نتیجه چندان جالب نیست - سیستم به سادگی برنامه ای را اجرا می کند که به صورت دوره ای کاراکتر "A" را نمایش می دهد.
حالا بیایید این گزینه را زمانی که نمونههای زیادی از یک برنامه در حال اجرا هستند، اما برای واضحتر شدن آن، حروف متفاوتی را خروجی میدهند، امتحان کنیم. در این صورت نتیجه تا حدودی متفاوت خواهد بود. با وجود اینکه ما یک پردازنده داریم، برنامه به طور همزمان اجرا می شود. چگونه اتفاق می افتد؟ اما معلوم می شود که سیستم عامل، نه بدون کمک قابلیت های سخت افزاری، یک توهم ایجاد می کند. این توهم که سیستم دارای چندین پردازنده مجازی است، یک پردازنده فیزیکی واحد را به یک تعداد تئوری بی نهایت تبدیل می کند و در نتیجه به برنامه های ظاهرا اجازه می دهد تا همزمان اجرا شوند. این توهم نامیده می شود مجازی سازی CPU.
این تصویر سوالات زیادی را ایجاد می کند، مثلا اگر چند برنامه بخواهند همزمان اجرا شوند، کدام یک راه اندازی می شود؟ "سیاست" سیستم عامل مسئول این سوال است. خطمشیها در بسیاری از مکانهای سیستمعامل استفاده میشوند و به سوالاتی از این دست پاسخ میدهند و مکانیزمهای اساسی هستند که سیستمعامل پیادهسازی میکند. از این رو نقش سیستم عامل به عنوان یک مدیر منبع.
مجازی سازی حافظه
حالا بیایید به حافظه نگاه کنیم. مدل فیزیکی حافظه در سیستم های مدرن به صورت آرایه ای از بایت ها نمایش داده می شود.. برای خواندن از حافظه، باید مشخص کنید آدرس سلولبرای دسترسی به آن برای نوشتن یا بهروزرسانی دادهها، باید دادهها و آدرس سلولی را که باید در آن بنویسید را نیز مشخص کنید.
حافظه در طول اجرای برنامه به طور مداوم در دسترس است. یک برنامه کل ساختار داده خود را در حافظه ذخیره می کند و با اجرای دستورالعمل های مختلف به آن دسترسی پیدا می کند. در همین حال، دستورالعمل ها نیز در حافظه ذخیره می شوند، بنابراین برای هر درخواست برای دستورالعمل بعدی نیز قابل دسترسی است.
malloc() فراخوانی کنید
برنامه زیر را در نظر بگیرید که با استفاده از تماس یک ناحیه از حافظه را اختصاص می دهد malloc () (https://youtu.be/jnlKRnoT1m0):
این برنامه چندین کار را انجام می دهد. ابتدا مقداری حافظه را اختصاص می دهد (خط 7)، سپس آدرس سلول اختصاص داده شده را چاپ می کند (خط 9)، صفر را در اولین شکاف حافظه اختصاص داده شده می نویسد. در مرحله بعد، برنامه وارد حلقه ای می شود که در آن مقدار ذخیره شده در حافظه در آدرس متغیر "p" را افزایش می دهد. همچنین شناسه فرآیند خود را چاپ می کند. شناسه فرآیند برای هر فرآیند در حال اجرا منحصر به فرد است. پس از راه اندازی چندین نسخه، به یک نتیجه جالب برخورد خواهیم کرد: در مورد اول، اگر کاری انجام ندهید و فقط چندین نسخه را اجرا کنید، آدرس ها متفاوت خواهند بود. اما این در تئوری ما نمی گنجد! درست است، زیرا توزیع های مدرن به طور پیش فرض تصادفی سازی حافظه را فعال کرده اند. اگر غیرفعال باشد، نتیجه مورد انتظار را دریافت می کنیم - آدرس های حافظه دو برنامه به طور همزمان در حال اجرا مطابقت دارند.
در نتیجه، معلوم می شود که دو برنامه مستقل با فضاهای آدرس خصوصی خود کار می کنند که به نوبه خود توسط سیستم عامل در حافظه فیزیکی نگاشت می شوند.. بنابراین، استفاده از آدرسهای حافظه در یک برنامه به هیچ وجه روی دیگران تأثیر نمیگذارد و به نظر میرسد هر برنامهای دارای حافظه فیزیکی خاص خود است که به طور کامل به آن داده شده است. اما واقعیت این است که حافظه فیزیکی یک منبع مشترک است که توسط سیستم عامل مدیریت می شود.
ثبات
یکی دیگر از موضوعات مهم در سیستم عامل ها - است ثبات. این اصطلاح زمانی استفاده می شود که در مورد مشکلاتی در سیستم صحبت می شود که ممکن است هنگام کار با بسیاری از چیزها به طور همزمان در یک برنامه اتفاق بیفتد. مشکلات سازگاری حتی در خود سیستم عامل نیز به وجود می آید. در مثالهای قبلی مجازیسازی حافظه و پردازنده، متوجه شدیم که سیستمعامل بسیاری از چیزها را همزمان مدیریت میکند - فرآیند اول را شروع میکند، سپس فرآیند دوم و غیره. همانطور که مشخص شد، این رفتار می تواند منجر به برخی مشکلات شود. بنابراین، به عنوان مثال، برنامه های مدرن چند رشته ای چنین مشکلاتی را تجربه می کنند.
برنامه زیر را در نظر بگیرید:
برنامه در تابع اصلی با استفاده از تماس دو رشته ایجاد می کند pthread_create(). در این مثال، یک رشته را می توان به عنوان تابعی در نظر گرفت که در فضای حافظه یکسان در کنار سایر توابع اجرا می شود، و به وضوح بیش از یک تابع همزمان اجرا می شود. در این مثال، هر نخ شروع شده و تابع را اجرا می کند worker() که به نوبه خود به سادگی متغیر را افزایش می دهد,.
بیایید این برنامه را با آرگومان 1000 اجرا کنیم. همانطور که ممکن است حدس بزنید، نتیجه باید 2000 باشد زیرا هر رشته متغیر را 1000 بار افزایش می دهد. با این حال، همه چیز به این سادگی نیست. بیایید سعی کنیم برنامه را با مرتبه تکرار بیشتر اجرا کنیم.
با وارد کردن عددی مثلا 100000 انتظار داریم خروجی را عدد 200000 ببینیم اما اگر عدد 100000 را چندین بار اجرا کنیم نه تنها جواب صحیح را نمی بینیم بلکه پاسخ های نادرست مختلفی نیز دریافت می کنیم. پاسخ در این واقعیت نهفته است که برای افزایش تعداد، سه عملیات لازم است - استخراج عدد از حافظه، افزایش و سپس نوشتن عدد. از آنجایی که همه این دستورالعمل ها به صورت اتمی (همه به طور همزمان) اجرا نمی شوند، موارد عجیبی مانند این ممکن است رخ دهد. این مشکل در برنامه نویسی نامیده می شود شرایط مسابقه. هنگامی که نیروهای ناشناخته در یک لحظه نامعلوم می توانند بر عملکرد هر یک از عملیات شما تأثیر بگذارند.