نکات کلیدی
1. هسته: هستهی برنامهنویسی سیستم
هستهی سیستمعامل: هسته.
نقش هسته. هسته قلب سیستمعامل است که منابع کامپیوتر مانند CPU، حافظه و دستگاهها را مدیریت میکند. این هسته به عنوان واسطهای بین برنامهها و سختافزار عمل میکند و یک رابط ثابت برای انجام وظایف توسط برنامهها فراهم میآورد. هسته مسئول زمانبندی فرآیندها، مدیریت حافظه، دسترسی به سیستم فایل و تعامل با دستگاهها است.
حالت کاربر در مقابل حالت هسته. هسته در یک حالت ویژه عمل میکند که به آن اجازه میدهد به تمام منابع حافظه و سختافزار دسترسی داشته باشد. برنامههای کاربر در یک حالت محدود اجرا میشوند که مانع از دسترسی مستقیم آنها به حافظه هسته یا انجام عملیات ویژه میشود. این جداسازی به حفظ ثبات و امنیت سیستم کمک میکند.
فراخوانیهای سیستمی. برنامههای کاربر از طریق فراخوانیهای سیستمی با هسته تعامل میکنند که نقاط ورودی کنترلشدهای به هسته هستند. این فراخوانیها به برنامهها اجازه میدهند تا خدماتی از هسته درخواست کنند، مانند ورودی/خروجی فایل، ایجاد فرآیند و ارتباطات شبکه. API فراخوانیهای سیستمی لینوکس محور اصلی این کتاب است.
2. ورودی/خروجی فایل: رابط جهانی
جهانی بودن ورودی/خروجی.
مدل ورودی/خروجی جهانی. سیستمهای UNIX، از جمله لینوکس، از یک مدل ورودی/خروجی جهانی استفاده میکنند که در آن از همان فراخوانیهای سیستمی (open()، read()، write()، close() و غیره) برای انجام ورودی/خروجی بر روی تمام انواع فایلها، از جمله فایلهای عادی، دستگاهها، لولهها و سوکتها استفاده میشود. این انتزاع برنامهنویسی را سادهتر کرده و قابلیت استفاده مجدد از کد را ترویج میدهد.
توصیفگرهای فایل. فایلهای باز با استفاده از توصیفگرهای فایل که اعداد صحیح کوچکی هستند، ارجاع داده میشوند. یک فرآیند سه توصیفگر فایل استاندارد را به ارث میبرد: 0 (ورودی استاندارد)، 1 (خروجی استاندارد) و 2 (خطای استاندارد). این توصیفگرها میتوانند به فایلها یا دستگاههای دیگر هدایت شوند.
بافرینگ. هم هسته و هم کتابخانه stdio بافرینگ ورودی/خروجی فایل را برای بهبود عملکرد انجام میدهند. هسته از یک بافر کش برای ذخیرهسازی دادهها در حافظه استفاده میکند که تعداد دسترسیهای دیسک را کاهش میدهد. کتابخانه stdio نیز از بافرها برای کاهش تعداد فراخوانیهای سیستمی استفاده میکند. درک بافرینگ برای نوشتن برنامههای کارآمد و قابل اعتماد بسیار مهم است.
3. فرآیندها: بنیاد اجرای برنامه
فرآیندها و برنامهها.
فرآیندها در مقابل برنامهها. یک برنامه فایلی است که شامل دستورالعملها و دادهها است، در حالی که یک فرآیند نمونهای از یک برنامه در حال اجرا است. هسته فرآیندها را مدیریت میکند و منابعی مانند زمان CPU، حافظه و توصیفگرهای فایل را تخصیص میدهد. هر فرآیند دارای یک شناسه فرآیند منحصر به فرد (PID) و یک شناسه فرآیند والد (PPID) است.
چیدمان حافظه. حافظه مجازی یک فرآیند به بخشهایی تقسیم میشود: متن (دستورالعملهای برنامه)، داده (متغیرهای جهانی اولیهگذاری شده)، هپ (حافظه تخصیصیافته بهطور دینامیک) و پشته (اطلاعات تماس تابع). هسته حافظه مجازی را مدیریت میکند و به هر فرآیند فضای آدرس جداگانهای ارائه میدهد.
ایجاد و خاتمه فرآیند. یک فرآیند جدید با استفاده از fork() ایجاد میشود که فرآیند والد را کپی میکند. سپس فرآیند فرزند میتواند از execve() برای بارگذاری و اجرای یک برنامه جدید استفاده کند. یک فرآیند با استفاده از _exit() یا exit() خاتمه مییابد و والد آن میتواند وضعیت خاتمه آن را با استفاده از wait() به دست آورد.
4. مدیریت حافظه: هنر تخصیص
تخصیص حافظه در هپ.
تخصیص هپ. فرآیندها میتوانند بهطور دینامیک حافظه را در هپ با استفاده از توابعی مانند malloc() و free() تخصیص دهند. هپ منطقهای از حافظه است که با تخصیص و آزادسازی حافظه بزرگ و کوچک میشود. هسته با تنظیم مرز برنامه، هپ را مدیریت میکند.
تخصیص پشته. پشته منطقهای از حافظه است که برای ذخیره متغیرهای محلی و اطلاعات تماس تابع استفاده میشود. تابع alloca() حافظه را در پشته تخصیص میدهد، اما این حافظه بهطور خودکار زمانی که تابع بازمیگردد آزاد میشود.
نقشهبرداری حافظه. فراخوانی سیستمی mmap() یک نقشهبرداری حافظه ایجاد میکند که میتواند برای نقشهبرداری یک فایل به حافظه یا ایجاد یک منطقه حافظه ناشناس استفاده شود. نقشهبرداریهای حافظه میتوانند بین فرآیندها به اشتراک گذاشته شوند و روشی سریع برای IPC فراهم کنند.
5. زمان و زمانبندی: کنترل جریان
زمان.
مفاهیم زمان. سیستمهای UNIX از زمان تقویمی (ثانیهها از زمان آغاز) و زمان فرآیند (زمان CPU استفاده شده توسط یک فرآیند) استفاده میکنند. هسته یک ساعت نرمافزاری را نگهداری میکند که زمان را در واحدهایی به نام jiffies اندازهگیری میکند.
تایمرها. فراخوانیهای سیستمی setitimer() و alarm() تایمرهای دورهای را ایجاد میکنند که هنگام انقضا سیگنال تولید میکنند. این تایمرها میتوانند برای تعیین زمانهای انقضا در عملیات مسدودکننده استفاده شوند.
خوابیدن. توابع sleep() و nanosleep() اجرای یک فرآیند را برای یک بازه زمانی مشخص متوقف میکنند. تابع POSIX clock_nanosleep() یک روش دقیقتر برای خوابیدن ارائه میدهد که از یک ساعت مشخص استفاده میکند.
زمانبندی فرآیند. زمانبند هسته تعیین میکند که کدام فرآیندها به CPU دسترسی پیدا میکنند. فرآیندها دارای یک مقدار nice هستند که بر اولویت آنها تأثیر میگذارد. سیاستهای زمانبندی زمان واقعی (SCHED_RR و SCHED_FIFO) کنترل دقیقتری بر زمانبندی فرآیندها فراهم میکنند.
6. سیگنالها: ارتباط ناهمزمان
سیگنالها: مفاهیم بنیادی.
مکانیسم سیگنال. سیگنالها نوعی اعلان ناهمزمان به یک فرآیند هستند که یک رویداد رخ داده است. سیگنالها میتوانند توسط هسته (مانند استثناهای سختافزاری، ورودی ترمینال)، توسط یک فرآیند دیگر یا توسط خود فرآیند تولید شوند.
مدیریت سیگنال. یک فرآیند میتواند تصمیم بگیرد که یک سیگنال را نادیده بگیرد، عمل پیشفرض آن را بپذیرد (مانند خاتمه) یا یک مدیریت سیگنال تعیین کند، که تابعی است که هنگام دریافت سیگنال فراخوانی میشود.
ماسک سیگنال. یک فرآیند میتواند با افزودن سیگنالهای خاص به ماسک سیگنال خود، تحویل برخی سیگنالها را مسدود کند. سیگنالهای مسدود شده تا زمانی که آزاد نشوند، در حالت معلق باقی میمانند. سیگنالها در صف قرار نمیگیرند؛ اگر در حین مسدود بودن، همان سیگنال چندین بار تولید شود، تنها یک بار تحویل داده میشود.
API سیگنال. تابع signal() API قدیمیتری برای تعیین مدیریتکنندههای سیگنال است، اما قابل حمل نیست. تابع sigaction() روش ترجیحی برای تعیین مدیریتکنندههای سیگنال است، زیرا کنترل بیشتری را فراهم میکند و قابل حملتر است.
7. رشتهها: اجرای همزمان
رشتهها: مقدمه.
رشتهها در مقابل فرآیندها. رشتهها مکانیزمی برای اجرای همزمان درون یک فرآیند واحد هستند. رشتهها همان حافظه مجازی، توصیفگرهای فایل و وضعیتهای سیگنال را به اشتراک میگذارند، اما هر رشته دارای پشته و شناسه رشته خود است.
API Pthreads. API Pthreads مجموعهای استاندارد از توابع برای ایجاد، خاتمه و همگامسازی رشتهها را فراهم میکند. تابع pthread_create() یک رشته جدید ایجاد میکند و pthread_exit() یک رشته را خاتمه میدهد. تابع pthread_join() منتظر خاتمه یک رشته میماند.
همگامسازی رشته. رشتهها از mutexها و متغیرهای شرطی برای همگامسازی دسترسی به منابع مشترک استفاده میکنند. Mutexها دسترسی انحصاری به یک متغیر مشترک را فراهم میکنند، در حالی که متغیرهای شرطی به رشتهها اجازه میدهند تا منتظر تغییرات در وضعیت یک متغیر مشترک باشند.
ایمنی رشته. توابع ایمن برای رشته میتوانند بهطور همزمان از چندین رشته فراخوانی شوند. توابع غیر ایمن برای رشته باید در برنامههای چندرشتهای اجتناب شوند. دادههای خاص رشته و ذخیرهسازی محلی رشته مکانیزمهایی برای ایمن کردن توابع غیر ایمن برای رشته بدون تغییر رابطهای آنها فراهم میکنند.
8. ارتباط بین فرآیندها: اشتراکگذاری دادهها و همگامسازی
مرور کلی ارتباط بین فرآیندها.
مکانیسمهای IPC. سیستمهای UNIX مجموعهای از مکانیسمها برای ارتباط بین فرآیندها (IPC) فراهم میکنند، از جمله لولهها، FIFOها، صفهای پیام، semaphoreها، حافظه مشترک و سوکتها. این مکانیسمها میتوانند برای تبادل دادهها و همگامسازی اقدامات فرآیندها استفاده شوند.
انتقال داده در مقابل حافظه مشترک. تسهیلات انتقال داده (لولهها، FIFOها، صفهای پیام، سوکتها) شامل کپی دادهها بین فرآیندها است، در حالی که حافظه مشترک به فرآیندها اجازه میدهد تا بهطور مستقیم به همان منطقه حافظه دسترسی پیدا کنند. حافظه مشترک سریعتر است، اما نیاز به همگامسازی صریح دارد.
IPC سیستم V در مقابل POSIX. مکانیسمهای IPC سیستم V (صفهای پیام، semaphoreها، حافظه مشترک) قدیمیتر و در دسترستر هستند، اما APIهای آنها پیچیدهتر و کمتر سازگار با مدل ورودی/خروجی سنتی UNIX هستند. مکانیسمهای IPC POSIX API سادهتر و سازگارتر را فراهم میکنند، اما در تمام پیادهسازیهای UNIX در دسترس نیستند.
9. سوکتها: اتصال در شبکهها
سوکتها: مقدمه.
سوکتها به عنوان IPC. سوکتها یک مکانیزم IPC چندمنظوره هستند که میتوانند برای ارتباط بین فرآیندها در همان میزبان (سوکتهای دامنه UNIX) یا بین فرآیندها در میزبانهای مختلف متصل به یک شبکه (سوکتهای دامنه اینترنت) استفاده شوند.
انواع سوکت. سوکتها به دو نوع اصلی تقسیم میشوند: سوکتهای جریانی (SOCK_STREAM) که یک کانال ارتباطی قابل اعتماد و دوطرفه برای جریان بایت فراهم میکنند و سوکتهای دیتاگرام (SOCK_DGRAM) که ارتباطی غیرقابل اعتماد و بدون اتصال و مبتنی بر پیام را فراهم میکنند.
عملیات سوکت. فراخوانیهای کلیدی سیستم سوکت شامل socket() (ایجاد یک سوکت)، bind() (بستن یک سوکت به یک آدرس)، listen() (علامتگذاری یک سوکت جریانی به عنوان غیرفعال)، accept() (پذیرفتن یک اتصال بر روی یک سوکت جریانی در حال گوش دادن) و connect() (اتصال به یک سوکت همتا) است.
سوکتهای دامنه اینترنت. سوکتهای دامنه اینترنت از آدرسهای IP و شمارههای پورت برای شناسایی نقاط پایانی ارتباط استفاده میکنند. توابع getaddrinfo() و getnameinfo() برای تبدیل بین نامهای میزبان و نامهای خدمات و نمایشهای عددی مربوطه استفاده میشوند.
10. ترمینالها و ترمینالهای مجازی: تعامل با کاربر
ترمینالها.
ویژگیهای ترمینال. ترمینالها دارای مجموعهای از ویژگیها هستند که نحوه عملکرد آنها را کنترل میکنند، از جمله کاراکترهای خاص، پرچمها و حالتهای ورودی/خروجی. این ویژگیها میتوانند با استفاده از توابع tcgetattr() و tcsetattr() بازیابی و تغییر یابند.
حالتهای ورودی/خروجی ترمینال. ترمینالها میتوانند در حالت کانونی (ورودی خط به خط) یا غیرکانونی (ورودی کاراکتر به کاراکتر) عمل کنند. حالت ورودی/خروجی ترمینال توسط پرچمهای ترمینال کنترل میشود.
ترمینالهای مجازی. ترمینالهای مجازی (ptys) یک جفت دستگاه مجازی متصل هستند، یک مستر و یک اسلوی. دستگاه اسلو یک رابط ارائه میدهد که مانند یک ترمینال عمل میکند، در حالی که دستگاه مستر وسیلهای برای کنترل اسلو فراهم میکند. ترمینالهای مجازی در برنامههای مختلفی از جمله پنجرههای ترمینال و خدمات ورود به شبکه استفاده میشوند.
کنترل ترمینال. فراخوانی سیستمی ioctl() برای انجام مجموعهای از عملیات کنترلی بر روی ترمینالها استفاده میشود، از جمله تنظیم ویژگیهای ترمینال، کنترل خط ترمینال و بهدست آوردن اندازه پنجره ترمینال.
11. امنیت و قابلیتها: حفاظت از سیستم
نوشتن برنامههای امن با امتیازات ویژه.
برنامههای ویژه. برنامههای ویژه به منابع سیستمی دسترسی دارند که برای کاربران عادی در دسترس نیست. چنین برنامههایی باید با احتیاط بسیار نوشته شوند تا از آسیبپذیریهای امنیتی جلوگیری شود.
کمترین امتیاز. برنامههای ویژه باید با کمترین امتیاز لازم برای انجام وظایف خود عمل کنند. این به معنای رها کردن امتیازات زمانی است که به آنها نیاز نیست و بهطور دائمی رها کردن امتیازات زمانی است که هرگز دوباره به آنها نیاز نخواهد بود.
اعتبارسنجی ورودی. برنامههای ویژه باید به دقت تمام ورودیها از منابع غیرقابل اعتماد، از جمله آرگومانهای خط فرمان، متغیرهای محیطی و دادههای فایلها و اتصالات شبکه را اعتبارسنجی کنند.
قابلیتها. طرح قابلیتهای لینوکس امتیاز ویژه سنتی را به واحدهای مجزایی به نام قابلیتها تقسیم میکند. این به یک فرآیند اجازه میدهد تا تنها امتیازاتی را که نیاز دارد، دریافت کند و در نتیجه پتانسیل آسیب را در صورت نفوذ برنامه کاهش دهد.
12. کتابخانههای مشترک: قابلیت استفاده مجدد از کد و کارایی
اصول کتابخانههای مشترک.
کتابخانههای شیء. کتابخانههای شیء فایلهایی هستند که شامل کد شیء کامپایلشده برای مجموعهای از توابع هستند. کتابخانههای ایستا در زمان کامپایل به یک اجرایی لینک میشوند، در حالی که کتابخانههای مشترک در زمان اجرا بارگذاری میشوند.
کتابخانههای مشترک. کتابخانههای مشترک به چندین فرآیند اجازه میدهند تا یک نسخه از کد کتابخانه را در حافظه به اشتراک بگذارند و در نتیجه فضای دیسک و RAM را صرفهجویی کنند. کتابخانههای مشترک همچنین اجازه میدهند تا بهروزرسانیهای کتابخانه بدون نیاز به لینک مجدد برنامهها اعمال شوند.
کد مستقل از موقعیت. کتابخانههای مشترک باید با استفاده از کد مستقل از موقعیت (PIC) کامپایل شوند که به کد کتابخانه اجازه میدهد در هر آدرسی در حافظه بارگذاری شود.
لینکگذاری دینامیک. لینککننده دینامیک مسئول بارگذاری کتابخانههای مشترک در زمان اجرا و حل ارجاعات نماد است. متغیر محیطی LD_LIBRARY_PATH میتواند برای مشخص کردن دایرکتوریهای اضافی که لینککننده دینامیک باید برای جستجوی کتابخانههای مشترک بررسی کند، استفاده شود.
قابلیت دید نماد. کتابخانههای مشترک باید تنها نمادهایی را که بخشی از API عمومی آنها هستند، صادر کنند. اسکریپتهای نسخه میتوانند برای کنترل قابلیت دید نماد و ایجاد نمادهای نسخهبندی شده استفاده شوند.
آخرین بهروزرسانی::
FAQ
What's The Linux Programming Interface about?
- Comprehensive Guide: The Linux Programming Interface by Michael Kerrisk is a detailed handbook on Linux and UNIX system programming, covering system calls, library functions, and the programming interface used by nearly every application on these systems.
- Focus on Standards: The book emphasizes UNIX standards (POSIX.1-2001/SUSv3 and POSIX.1-2008/SUSv4), making it valuable for programmers working on various UNIX platforms.
- Practical Examples: It includes over 200 example programs, 88 tables, and 115 diagrams to illustrate concepts, making it easier for readers to grasp complex topics.
Why should I read The Linux Programming Interface?
- Authoritative Resource: Written by Michael Kerrisk, a recognized expert in Linux programming, this book is considered the definitive guide in the field. It is praised for its clarity and depth.
- Skill Development: The book is designed for programmers and software designers looking to build applications for Linux or other UNIX systems, enhancing their system programming skills.
- Comprehensive Coverage: It covers a wide range of topics, from basic file I/O to advanced features like multithreading and interprocess communication, making it suitable for both beginners and experienced developers.
What are the key takeaways of The Linux Programming Interface?
- Understanding System Calls: Readers will learn how to effectively use system calls and library functions, which are crucial for interacting with the Linux kernel.
- File I/O Model: The book introduces the universal I/O model, explaining how the same system calls are used for all types of files, including devices and sockets.
- Error Handling: It emphasizes the importance of checking return values from system calls and library functions, teaching readers how to handle errors effectively.
What are the best quotes from The Linux Programming Interface and what do they mean?
- Comprehensive Coverage: “The Linux Programming Interface is the most comprehensive single-volume work on the Linux and UNIX programming interface.” This highlights the book's extensive coverage and authority in the field.
- Depth of Content: “You’ll find descriptions of over 500 system calls and library functions.” This emphasizes the book's depth, indicating a thorough exploration of the programming interface.
- Transferable Knowledge: “The emphasis on UNIX standards makes it equally valuable to programmers working on other UNIX platforms.” This suggests that the knowledge gained is applicable across different UNIX systems.
How does The Linux Programming Interface explain system calls?
- Definition of System Calls: System calls are controlled entry points into the kernel that allow processes to request services, such as file operations or process management.
- Kernel Interaction: They enable user programs to interact with the kernel, which manages system resources and enforces security and access controls.
- Performance Overhead: Understanding the overhead associated with system calls is crucial for writing efficient programs, as they involve switching from user mode to kernel mode.
What is the universal I/O model discussed in The Linux Programming Interface?
- Unified System Calls: The universal I/O model states that the same system calls (open(), read(), write(), close()) are used for all types of files, including regular files, pipes, and sockets.
- Simplified Programming: This model simplifies the programming model, allowing developers to write code that works across different file types without needing to handle each type differently.
- Practical Examples: The book provides examples that illustrate how to use these system calls effectively, reinforcing the concept of universality in file I/O.
How does The Linux Programming Interface address error handling?
- Importance of Error Checking: The book stresses that every system call and library function should have its return value checked to ensure successful execution.
- Using errno: It explains how to use the global variable
errno
to diagnose errors, providing functions likeperror()
andstrerror()
for user-friendly error messages. - Example Implementation: The book includes practical examples demonstrating how to handle errors effectively, which is essential for robust programming.
What are the differences between static and shared libraries as explained in The Linux Programming Interface?
- Static Libraries: These are archives of object code that are linked into an executable at compile time, resulting in larger binaries and requiring recompilation for updates.
- Shared Libraries: These are linked at runtime, allowing multiple programs to share a single copy of the library in memory, which saves space and simplifies updates.
- Advantages of Shared Libraries: The book discusses how shared libraries facilitate easier updates and reduce memory usage, making them preferable in many scenarios.
How does The Linux Programming Interface explain process management?
- Definition of a Process: A process is defined as an instance of an executing program, with its own memory space and resources managed by the kernel.
- Process Creation: The book details how processes are created using the fork() system call, which duplicates the parent process, and how they can execute new programs using execve().
- Process Management: It covers how the kernel manages processes, including scheduling, resource allocation, and termination, providing a comprehensive understanding of process behavior.
What is the significance of the /proc file system in The Linux Programming Interface?
- Virtual File System: The /proc file system is a virtual file system that provides an interface to kernel data structures, allowing users to view and modify system attributes.
- Process Information: It contains directories for each running process, providing insights into process states and resource usage, which is invaluable for debugging and monitoring.
- Kernel Interaction: The book explains how to interact with /proc files to gather system information, making it a practical tool for system programmers.
How does The Linux Programming Interface explain interprocess communication (IPC)?
- Diverse IPC Methods: The book covers various IPC methods, including pipes, message queues, and shared memory. Each method is explained with examples, allowing readers to understand their use cases and implementation.
- Synchronization Techniques: It also discusses synchronization mechanisms, such as semaphores and mutexes, which are crucial for coordinating access to shared resources.
- Practical Examples: The author provides practical examples of IPC in action, demonstrating how to implement these techniques in real-world applications.
What are the threading concepts discussed in The Linux Programming Interface?
- POSIX Threads: The book provides a comprehensive overview of POSIX threads, including thread creation, termination, and synchronization. This is essential for developing multithreaded applications in Linux.
- Thread Safety: It emphasizes the importance of writing thread-safe code, discussing techniques to manage shared resources and avoid race conditions.
- Cancellation and Cleanup: The book covers thread cancellation and the use of cleanup handlers, which are important for managing resources in multithreaded programs.
نقد و بررسی
کتاب رابطه برنامهنویسی لینوکس با استقبال بسیار مثبت خوانندگان مواجه شده است و آنها به خاطر پوشش جامع آن در زمینه برنامهنویسی سیستم لینوکس از آن تمجید میکنند. بسیاری این کتاب را بهعنوان یک مرجع قطعی توصیف کرده و بر توضیحات روشن، مثالهای عملی و زمینه تاریخی آن تأکید میکنند. خوانندگان به عمق، سازماندهی و قابلیت خواندن این کتاب، با وجود حجم قابل توجه آن، ارج مینهند. این کتاب به خاطر پیوند دادن مفاهیم نظری با کاربردهای عملی مورد ستایش قرار گرفته و برای یادگیری و مرجع بسیار ارزشمند است. بسیاری از نقدکنندگان زمان قابل توجهی را با این کتاب سپری کرده و آن را برای درک عمیقتر از جزئیات لینوکس و فراخوانیهای سیستم مفید میدانند.
Similar Books









