进程特征

结构

程序是一组有序指令的集合,静态的存放于某种介质。为使程序能独立运行,配置一进程控制块PCB(Process Control Block),由程序段,数据段和PCB三部分便构成了进程实体。所谓创建进程,实质上是创建进程实体中的PCB,撤销进程,实质上是撤销进程的PCB

动态性

进程的实质是进程实体的一次执行过程,由创建而产生,由调度而执行,由撤销而消亡。

并发性

多个进程实体同时存在于内存中,且能在一段时间内同时运行。程序(没有PCB)是不能并发执行的。

独立性

进程实体是一个能独立运行,独立分配系统资源和独立接收调度的基本单位。

异步性

进程按各自独立的,不可预知的速度向前推进,或者说进程是按异步方式运行的。

进程三种基本状态

进程执行时的间断性决定了进程具有多种状态。

就绪状态

进程已分配到除CPU以外的所有必要资源(内存,I/O设备),只要获取CPU,便可立即执行。此时为就绪状态,存在于就绪队列

执行状态

进程获得CPU,正在执行。单处理机中只有一个进程处于执行状态,多处理机中有多个进程处于执行状态。

阻塞状态

正在执行的进程由于发生某事件(请求I/O,申请缓冲区,访问临界资源)而暂时无法继续执行,便放弃处理机而处于阻塞状态。存在于阻塞队列。 63c449f537f50eeb72b123a7c22a9e7c

创建状态

为一个新进程创建PCB,并填写必要管理信息,把进程转入就绪状态并插入就绪队列中。

终止状态

当一个进程到达了自然结束点,或是出现了致命错误,或是被OS终结,将进入终止状态。 等待操作系统进行善后处理,然后将其PCB清零,并将PCB空间返还系统。 ad8e2acb3ec83dd1a38570fdb6d7b967

挂起状态

原因:

  • 终端用户请求,终端用户可在自己程序运行期间发现问题,暂时使程序静止
  • 父进程请求,父进程挂起子进程
  • 负荷调节需要,系统中工作负荷较重,可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起
  • 操作系统需要 b069977662e7e148ebde8dce0e0648ec

进程控制块

  • 作用
    1.PCB用于描述和控制进程的运行,linux中用task_struct数据结构来描述每个进程的进程控制块。
    2.系统将所有PCB组织成若干个链表或队列,存放在OS中专门开辟的PCB区内。
  • 基本信息
    1.进程标识符,唯一标识一个进程。
    2.处理机状态
    3.进程调度信息,进程状态,进程优先级,其他信息
    4.进程控制信息,程序和数据地址,进程同步和通信机制,资源清单,链表指针,指向下一个PCB的首地址。

进程

进程创建

  • 进程图 6c607e4f9a9200c81c4d088b09b4a145 用于描述一个进程家族关系的有向树。子进程可以继承父进程所拥有的资源,如继承父进程打开的文件,继承父进程所分配的缓冲区等。
  • 进程创建
    1.申请空白PCB。申请唯一标识符,并从PCB集合中索取一个空白PCB
    2.为新进程分配资源。
    3.初始化进程控制块
    4.将新进程插入就绪队列。
  • 进程终止,引起进程终止的事件
    1.正常结束
    2.异常结束,越界错误,非法指令,等
  • 进程的阻塞和唤醒
    1.请求系统服务,如访问已分配给其他进程的打印机。如访问被锁住的共享资源
    2.启动某种操作。如I/O设备
    3.新数据未到达,阻塞等待。
    4.等待新任务。

阻塞过程,进程阻塞式进程自身的一种主动行为。利用block原语(原子操作)把进程控制块中的状态改为阻塞,并将PCB插入阻塞队列。
唤醒过程,当被阻塞进程期待的时间出现时,如I/O完成或网络数据到达,由相关进程的调用唤醒原语唤醒。首先把阻塞的进程从等待时间的阻塞队列移除,将PCB状态改为就绪,插入就绪队列等待调度。

线程

  • 操作系统引入进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量。线程则是为了减少程序在并发执行时所付出的空间切换开销,使OS具有更好的并发性。
  • 进程:1.拥有资源的独立单位 2.可独立调度和分派的单位 为使程序能并发执行,系统还必须进行1.创建进程,撤销进程,进程切换操作。切换时需要保留当前进程CPU环境和新进程CPU环境,系统必须为此付出较大的时间空间开销。所以在系统中所设置的进程数目不宜过多,进程切换频率不宜过大,就限制了并发程度的进一步提高。
  • 把进程的2个属性分开处理,提供并发性。线程作为调度和分派的基本单位,但不作为拥有资源的单位。
  • 进程至少有一个线程。

线程特性

轻型实体

包括一些必不可少的,保证其独立运行的资源。线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量,少数状态参数和返回地址等的一组寄存器和堆栈。

独立调度和分派的基本单位

线程是很轻量级的,线程切换非常迅速且开销小

可并发执行

一个进程中的多个线程,不同进程中的线程都能并发执行

共享进程资源

进程中的线程都具有相同的地址空间,可以访问进程所拥有的文件,定时器,信号量等

线程状态

如传统进程一样,各线程间也存在共享资源和相互合作制约,使得线程也是间断性的往前推进运行。
1.执行状态,线程正获得处理机而运行
2.就绪状态,线程已具备各种资源(内存,I/O设备),获得CPU便可执行
3.阻塞状态

多线程OS中的进程

1.作为系统资源分配的单位。资源包括:受到保护的用户地址空间,用于实现进程间和线程间同步和通信的机制,已打开的文件和已申请到的I/O设备,以及一张由核心进程维护的地址映射表,该表用于实现用户程序的逻辑地址到其内存物理地址的映射。
2.可包括多个线程。进程为线程提供资源及运行环境,使得线程可并发执行
3.进程不再是一个可执行实体。多线程OS中,是把线程作为独立运行的基本单位。

线程和进程比较

调度
  • 线程作为可调度和分派的单位能够提高系统并发性
  • 同一个进程中,线程切换不会引起进程切换,但从一个进程的线程切换到另一个进程的线程,会引起进程切换。
并发性

进程间可以并发执行,一个进程中的多个线程之间也可以并发执行,使得操作系统具有更好的并发性,提高系统资源的利用率和吞吐量。

拥有资源

进程拥有资源,是系统中拥有资源的基本单位。进程中的线程不拥有资源,但可访问隶属进程的资源,如一个进程的代码段,数据段和所拥有的系统资源,打开的文件,I/O设备等。

系统开销
  • 创建和撤销进程时,系统创建和回收进程控制块,分配回收资源的开销明显大于线程创建或撤销的开销。
  • 线程切换仅需保存和设置少量寄存器内容,不涉及存储器管理方面操作
  • 一个进程中的多个线程具有相同的地址空间,在同步和通信的实现比进程容易。

线程同步和通信

互斥锁(mutex)

互斥锁是一种简单的,用于实现线程间对资源互斥访问的机制,保证对临界资源的互斥访问。一个线程访问共享数据时,首先对该数据设置mutex执行关锁命令,如果已处于关锁,则线程被阻塞。
容易发生死锁:
1.同一个线程先后两次Lock,第二次由于锁已经被自己占用,该线程会等待释放锁,由于已被挂起没机会释放锁,将会一直处于等待状态。
2.线程A对mutex1关锁,进入临界区C,若在C内该线程又访问临界资源R,此时线程B已经访问R,并对mutex2关锁,线程A进入阻塞,如果线程B也要进入临界区C,但mutex1被线程A锁住。这样就形成了相互等待,死锁。

条件变量

为了解决死锁问题,引入条件变量,每一个条件变量通常与一个互斥锁使用。互斥锁用于短期锁定,保证临界区的互斥访问,条件变量用于线程的长期等待,直至所等待的资源成为可用。

process_msg(void)
{
	struct msg *mp;
	for (;;) {
	pthread_mutex_lock(&qlock);
	while (workq == NULL)
		pthread_cond_wait(&qready, &qlock);
	mp = workq;
	workq = mp->m_next;
	pthread_mutex_unlock(&qlock);
	/* now process the message mp */
	}
}
void
enqueue_msg(struct msg *mp)
{
	pthread_mutex_lock(&qlock);
	mp->m_next = workq;
	workq = mp;
	pthread_mutex_unlock(&qlock);
	pthread_cond_signal(&qready);
}

pthread_cond_wait 作用是把调用线程放到条件等待队列,释放mutex,且是原子操作。唤醒的只能是在条件变量上等待的某一个线程,其他线程继续等待。 参考:https://www.cnblogs.com/harlanc/p/8596211.html#_label2_0