CPU
↓
I/O
↓
CPU
↓
I/O
↓
CPU
یا مدت اجرای برنامه به ورودی کاربر وابسته باشه
پس اینکه از قبل دقیقا بدونیم هر Job چقدر CPU لازم داره همیشه ممکن نیست
اینجاست که Scheduling از یک صف ساده خیلی پیچیده تر میشه
چرا این موضوع برای ما مهمه؟
شاید اولش فکر کنید این بحث چه ربطی به Reverse Engineering داره
ولی وقتی یک برنامه چند تا Thread داشته باشه اجرای واقعی برنامه فقط به ترتیب دستورهای داخل Binary بستگی نداره
مثلا:
Thread A
↓
Running
↓
Preempted
همزمان:
Thread B
↓
Running
↓
Blocked
بعد دوباره:
Thread A
↓
Running
یعنی اجرای برنامه میتونه بین Thread های مختلف جابهجا بشه
این موضوع وقتی مهم تر میشه که با چیزهایی مثل اینها طرف باشیم:
Multi-threading
Race Condition
Deadlock
Timing Bug
Synchronization
مثلا ممکنه یک Bug فقط زمانی اتفاق بیفته که دو Thread تقریبا همزمان به یک بخش خاص از برنامه برسن
پس فقط نباید بپرسیم:
این دستور چی کار میکنه
باید بپرسیم:
این Thread کی اجرا شده؟ قبلش چه Thread ی اجرا شده؟ چرا اجرای این Thread متوقف شده و بعد دوباره برگشته؟
این دید بعدا برای تحلیل Bug های مربوط به Concurrency خیلی مهم میشه
فعلاً این سه معیار رو خوب یاد بگیرید:
Turnaround Time
Arrival → Completion
یعنی کل زمانی که Job از ورود تا پایان داخل سیستم بوده
Waiting Time
مدت انتظار برای CPU
یعنی چه مقدار از زمان Process در Ready Queue منتظر CPU بوده
Response Time
Arrival → First Run
یعنی چقدر طول کشیده تا Process برای اولین بار CPU بگیره.
به شکل خلاصه:
Arrival
│
├──── Waiting ────┐
│ │
▼ ▼
First Run Running
│ │
│ │
└── Response │
│
▼
Completion
Turnaround = Arrival → Completion
پس وقتی میخوایم دو الگوریتم Scheduling رو با هم مقایسه کنیم فقط نمیگیم:
کدوم سریعتره؟
باید ببینیم:
چقدر منتظر موندیم؟
چقدر سریع اولین جواب رو گرفتیم؟
چقدر طول کشید کار کامل بشه؟
اینها همون معیار هایی هستن که کمک میکنن بفهمیم یک Scheduler واقعا چقدر خوب عمل میکنه
@reverseengine
Post #1832
40