线程操作系统基础

程序与进程
程序:可执行文件及其相应的数据文件;程序是静态的;
进程:这是一个动态的概念(只是,进程有:产生、执行、结束的声明周期);进程和数据是密不可分的。

多道程序执行环境:是指多个程序“同时”执行的操作系统环境;对于单CPU系统而言,在时间点上,CPU一次只能执行一条语句,
而这一条语句又只能是多个程序中的某一个程序的语句。由于CPU速度很高,能“轮流”执行不同程序的相关指令,因此,在“宏观”角度
上说,多个程序是“同时”执行的。

单道程序系统与多道程序系统在执行多个程序时的差别:
假设现在有两个进程:A进程和B进程,且其内容各自如下:
    A进程                B进程
    a.1    ++i;        b.1 i += 10;
    a.2    --i;        b.2 输出i;
    a.3    输出i;        b.3 ++i;
    a.4 i += 3;
假设A进程先执行。
在单道程序环境中,必须等到A进程的语句全部执行完,才能执行B进程的相关指令;在这种情况下,程序语句的执行过程是固定的:
a.1->a.2->a.3->a.4->b.1->b.2->b.3
但是,在多道程序执行环境中,由于CPU是轮流执行多个进程的相关指令的,因此,会出现比较复杂的执行指令序列!
a.1->a.2->b.1->a.3->b.2->b.3->a.4
若上述的A进程和B进程之间存在共享内存某变量(空间),且各自对该变量进行操作,那么,在这种指令序列执行时“混乱”的情况下,
共享变量的值将在不同次执行情况下,其内容会有所不同;
上述讲述的是问题来源,如何在多道程序执行环境中能对程序的行为有所约束,使其不再“混乱”,这就是问题本身。

进程由:产生、调度、终结三种基本生存状态;在调度状态又存在下面三种状态:
进程的三种基本状态及相互之间的转换
1、就绪态;
2、运行态;
3、阻塞态。

就绪态:该进程已在内存中,且除了CPU这个资源外,其它资源均已满足;等待CPU执行其代码;进程的调度是由操作系统的专门的进程
    执行的,这个进程成为“进程调度进程”;
运行态:该进程正在被CPU执行着它的代码,又称:该进程占有CPU。
阻塞态:该类进程由于缺少(不满足)某些资源而不得不进入“等待资源”的状态,而这种等待往往是“耗时”的,因此,这些“阻塞态”中的
    进程不再参与到CPU竞争行列(就绪态)中。
    
运行态的进程最多1个;
就绪态进程可以有多个;
阻塞态进程,根据该进程等待的资源类型不同,进行“分组”,将等待同一类(个)资源的多个进程,以队列的方式排在该类资源的阻塞队列中;
    这可以得到结论:阻塞态是由多个阻塞队列组成,每个队列中有多个等待相同资源的阻塞进程。

由运行态转换为阻塞态,一定是由进程本身“申请”的;自我阻塞
由阻塞态转换为就绪态,一定是由其它进程“唤醒”的;他人唤醒
    阻塞态的进程“无权”执行!不可能运行!

进程之间的协作:
进程的互斥与同步
原语:原的意思是原子;不可分割的意思;更确切地说,这样的语句或语句组在执行时,是不能被“打断”的;
    进程创建原语;
    进程销毁原语;
    调度原语;
    阻塞原语;
    唤醒原语……
共享资源:多个进程共享内存空间或者其它资源;
临界区(资源):是指进程中对共享资源进行相关操作的那些代码及代码集合;每个进程都有各自(独立)的临界区;
    它们是通过共享资源发生联系的;
信号量:是为了解决进程同步、互斥操作的一个共享资源(简单地说,可以是一个int变量);

P、V操作
P原语和V原语都访问信号量s
    P(s)                V(s)
    --s;                ++s;
    if(s < 0)            if(s <= 0)
        阻塞原语;                唤醒原语;

利用P/V操作,实现A进程与B进程“临界区”的互斥进入。
    s的初值为1
    A进程            B进程            C进程
    P(s)        P(s)        P(s)
    A临界区        B临界区        C临界区
    V(s)        V(s)        V(s)
假设运行情况一:
A:P(s)->s:0->A临界区->B:P(s)->s:-1->B进程进入阻塞态->A临界区执行完毕->A:V(s)->s:0->唤醒B进程->
B临界区->A:P(s)->s:-1->A进程进入阻塞态
假设运行情况二:
B:P(s)->s:0->B临界区->A:P(s)->s:-1->A进程进入阻塞态->C:P(s)->s:-2->C进程进入阻塞->B临界区->...->
B:V(s)->s:-1(为保证互斥进入临界区,那么,此时只能唤醒一个进程)按照队列操作顺序,A进程将被唤醒,且A进程现在就在临界区
->A临界区->A:V(s)->s:0->唤醒C进程->C进程已经在临界区,而A进程和B进程刚刚执行外V(s)->C:V(s)->s:1

进程同步关系:
消费者与生产者;假设A进程是生产者,它生产“砖”;B进程是消费者,它“消费”砖。这里存在一个“莫须有”的条件:生产者在生产出转之前,
消费者无法消费“砖”;消费者在没有消费掉“砖”之前,生产者不能再生产其它砖!(假设两者之间通过一个篮子放砖和取砖)
其实这里存在一种“隐含”资源:就是那个篮子!即,空间!也就是说,生产者生产砖的同时,在消费“篮子”;消费者在消费砖的同时在生产“篮
子”。因此,这里存在两个信号量,一个是表示砖的信号量,一个表示篮子的信号量!
假设s砖表示砖;s蓝表示篮子。明显,s砖初值为0;s篮初值为1!
    生产者                消费者
    P(s蓝)                P(s砖)
    临界区(生产砖);            临界区(消费砖);
    V(s砖)                V(s蓝)
情况一:
生产者:P(s蓝)->s蓝:0->生产砖->消费者:P(s砖)->s砖:-1->消费者进入阻塞态->生产砖->V(s砖)->s砖:0->唤醒消费者
->生产者:P(s蓝)->s蓝:-1->生产者进入阻塞态->消费砖->消费砖->V(s蓝)->s蓝:0->唤醒生产者

从上述可得到一个非常重要的结论:关于信号量的物理意义!
信号量其实就是表示(控制)进程共享的“独占”资源的量;
信号量的初值其实就是资源的数量;
信号量值为0,表示相关资源已被“用尽”,但是,尚未有进程进入该资源的阻塞队列;
信号量为负值,其绝对值表示,在这个信号量(资源)上阻塞的进程数量。
假设n个进程和m个资源(n >= m)
s初值为m;
最多有多少个进程能在得到相关资源的情况下处于运行态或就绪态:m个进程;
最多有多少个进程会在该资源的阻塞队列中“排队”(进入阻塞态的进程最大数量):n-m。

原文地址:https://www.cnblogs.com/wzQingtTian/p/10659913.html