进程与线程

 

进程与线程 

在说进程和线程前,先说下程序的概念,程序就是为完成特定任务、用某种语言编写的一组指令的集合。指一段静态的代码。下面接着说进程和线程。

记得在刚接触这两个概念时,是这样说的,进程是程序的一次执行过程,是系统进行调度和资源分配的一个独立单位。线程是指程序的一个指令执行序列,是比进程更小的执行单位。感觉那时学的一点也不明白。这几天看了写资料,整理了一下。感觉进程的概念这样定义较好,进程是可并发执行的程序在一个数据集合上的运行过程。这个也许较第一个有些抽象,但是包含的内容还是挺多的。

先用电脑系统上的一个例子形象的说明一下进程和线程:

简单的说,你每启动一个程序,就启动了一个进程。在Windows 3.x下,进程是最小运行单位。在Windows 95/NT下,每个进程还可以启动几个线程,比如每下载一个文件可以单独开一个线程。在Windows 95/NT下,线程是最小单位。WINDOWS的多任务特性使得线程之间独立运行,但是它们彼此共享虚拟空间,也就是共用变量,线程有可能会同时操作一片内存。WIN32 平台支持多线程程序,允许程序中存在多个线程。在单CPU 系统中,系统把CPU 的时间片按照调度算法分配给各个线程,因此各线程实际上是分时执行的,在多CPU 的 Windows NT 系统中,同一个程序的不同线程可以被分配到不同的 CPU 上去执行。

进程和线程的一些谨记:

  • 一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。
  • 每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。
  • 一个线程有它自己的入口和出口,以及一个顺序执行的序列
  • 线程不能独立存在,必须存在于进程中。
  • 线程 — 轻量级的进程(lightweight processes)
    系统负担小,主要是CPU的分配。

线程和进程的比较

     进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。
另外,进程也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。

      与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。
  当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。

  线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。

  发生进程切换与发生线程切换时相比较,进程切换时涉及到有关资源指针的保存以及地址空间的变化等问题;线程切换时,由于同不进程内的线程共享资源和地址 空间,将不涉及资源信息的保存和地址变化问题,从而减少了操作系统的开销时间。而且,进程的调度与切换都是由操作系统内核完成,而线程则既可由操作系统内 核完成,也可由用户程序进行。

一个线程必须处于如下四种可能的状态之一

初始态:一个线程调用了new方法之后,并在调用start方法之前的所处状态。在初始态中,可以调用start和stop方法。

Runnable:一旦线程调用了start 方法,线程就转到Runnable 状态,注意,如果线程处于Runnable状态,它也有可能不在运行,这是因为还有优先级和调度问题。

阻塞/ NonRunnable:线程处于阻塞/NonRunnable状态,这是由两种可能性造成的:要么是因挂起而暂停的,要么是由于某些原因而阻塞的,例如包括等待IO请求的完成。 退出:线程转到退出状态,这有两种可能性,要么是run方法执行结束,要么是调用了stop方法。

最后一个概念就是线程的优先级,线程可以设定优先级,高优先级的线程可以安排在低优先级线程之前完成。一个应用程序可以通过使用线程中的方法setPriority(int),来设置线程的优先级大小。

线程有5种基本操作:

 派生:线程在进程内派生出来,它即可由进程派生,也可由线程派生。
 阻塞(Block):如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。
 激活(unblock):如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。
 调度(schedule):选择一个就绪线程进入执行状态。
 结束(Finish):如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。


线程有两个基本类型

 用户级线程:管理过程全部由用户程序完成,操作系统内核心只对进程进行管理。
 系统级线程(核心级线程):由操作系统内核进行管理。操作系统内核给应用程序提供相应的系统调用和应用程序接口API,以使用户程序可以创建、执行、撤消线程。



以下是用C语言实现的进程操作的程序,可实现简单的P、V操作。

/******************************************/
/* pipe.c 程序清单 */
/******************************************/
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include<stdlib.h>

main(){
pid_t pid; /*进程名为pid*/
int fds1[2],fds2[2] ,i=0, j=0;
char buf1[50],buf2[50],buf3[50],buf4[50];/*创建四个缓冲区*/

pipe(fds1); /*创建管道1*/
pipe(fds2); /*创建管道2*/

if((pid = fork()) < 0) /*进程创建失败,调用退出函数*/
{
printf("/n *****fork error /n");
exit(1);
}
else if(pid == 0) /*创建的是父进程*/
{
while(1){
sprintf(buf1,"%d child process print!" , rand()); /*把字符串child process print!写道缓冲区1 中,rand是随机数产生器*/
write(fds1[1],buf1,50); /*把buf1中的信息写道管道1中*/
read(fds2[0],buf2,50); /*从管道2中读取信息到buf2中*/
i=(int)buf2[0]%10;
sleep(i); /*睡1~10中随机的一个秒数*/
printf("%s,%d sleeping %d/n",buf2,getpid(),i);
}
}
else /*创建的是子进程*/
{
while(1){
read(fds1[0],buf3,50); /*从管道1中读取信息到buf3中*/
j=(int)buf3[0]%10;
printf("%s,%d sleeping %d/n",buf3,getpid(),j);
sleep(j); /*睡1~10中随机的一个秒数*/
sprintf(buf4,"%d Parent process print!" , rand()); /*把字符串child process print!写道缓冲区4中,rand是随机数产生器*/
write(fds2[1],buf4,50); /*把buf4中的信息写道管道2中*/

}
}
}

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值