学习了操作系统“双挂起进程模型”后老师引出了一个有意思的问题,就此开启操作系统学习记录···
传说有这样一段代码:
#include <stdio.h>
#include <windows.h>
#include <iostream.h>
#include <winbase.h>
void SubThread(void)
{
int i;
for (i=0;i<5;i++)
{
cout << "SubThread" << i << endl;
Sleep(2000);//改一下时间,输出顺序会有变化
}
}
void main(void)
{
cout << "CreateThread" << endl;
// Create a thread;创建线程
DWORD IDThread;
HANDLE hThread;
hThread = CreateThread(NULL, // no security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE) SubThread, // thread function
NULL, // no thread function argument
0, // use default creation flags
&IDThread); // returns thread identifier
// Check the return value for success.
if (hThread == NULL)
cout << "CreateThread error" << endl;
int i;
for (i=0;i<5;i++)
{
cout << "MainThread" << i << endl;
if (i==1)
{
if (SuspendThread(hThread)==0xFFFFFFFF)
{
cout << "Suspend thread error." << endl;
}
else
{
cout << "Suspend thread is ok." << endl;
}
}
if (i==3)
{
if (ResumeThread(hThread)==0xFFFFFFFF)
{
cout << "Resume thread error." << endl;
}
else
{
cout << "Resume thread is ok." << endl;
}
}
Sleep(4000);//改一下结果会有变化。
}
}
运行结果为:
CreateThread
MainThread0//输出后。 Sleep(4000)
SubThread0//输出后,Sleep(2000)
SubThread1 //输出后,Sleep(2000)
MainThread1//输出后。 Sleep(4000)
Suspend thread is ok.
MainThread2
MainThread3
Resume thread is ok. //输出后。 Sleep(4000)
SubThread2
SubThread3
MainThread4
SubThread4
课堂上大家众说纷纭,而本人被绕来绕去脑子都糊了,听老师讲解后现在大概用自己的话结合简陋的图解释一下正确过程(紧扣五态图)。
从main函数开始执行,输出“CreateThread”,此时的主函数咱们起个名不妨叫做M进程,此时M正处于CPU中运行。
CreateThread函数姑且不讨论内部具体参数,只要知道它创建了一个线程,我们不妨叫做S线程。在这里线程和进程的区别不作介绍,可以简单认为线程是进程中执行运算的最小单位,是进程中的一个实体。hThread是S线程的句柄。由于创建成功,所以不会输出 “CreateThread error”,S线程正在就绪态等待运行(因为运行态M进程正在占用)。如下简图1。
图1
M继续顺序执行到for循环,输出“MainThread0”,两次条件判断不符合进入睡眠状态。注意!!!此时的Sleep(4000)对进程状态图的改变为将M从运行态送至阻塞态!此时运行态空位,S线程进入执行,输出“SubThread0”,S紧接着又进入阻塞态,但由于S阻塞时间比M短,所以S先“苏醒”又从就绪态到了运行态,继续输出“SubThread1”,输出后又进入阻塞。如下简图2。
图2
此时M已经足够苏醒,M从就绪进入运行,此时for循环i变为1,输出“MainThread1”,符合第一个判断,S被挂起到外存,因而进入阻塞挂起状态,输出“Suspend thread is ok.”后M又进入阻塞区“睡眠”。如下简图3/4/5。
图3
图4
图5
S被送入阻塞挂起后就算醒来也只能到就绪挂起态,必须被激活才能进到内存被CPU执行,故S暂时没法回到内存,暂时S无法和M“抢资源”了。如下图6。
图6
于是M又绕一圈输出“MainThread2”、阻塞、苏醒、输出“MainThread3”,此时第二个判断符合,输出“Resume thread is ok.”,S被激活,进入就绪态。回到图1状态。M接着睡眠,S进入运行态,回到图2状态,输出“SubThread2”、“SubThread3”,接着M进入运行态,输出“MainThread4”,然后S进入输出“SubThread4”,最后M和S都结束消亡。
每天进步一点点,一起加油!