-
进程与线程
2016-04-04 20:51:20进程与线程进程与线程
进程
进程是程序的一次执行活动,是系统进行资源分配和调度的一个独立单位,程序是静态的,进程是动态的。
线程
线程是一个进程内部的一个控制序列,我的理解为线程是进程的一个的功能块
线程的优点
- 易于调度
- 提高了并发性
- 开销小(线程对资源的需求远小于进程)
线程与进程的区别
- 一个线程只能属于一个进程,一个进程可以拥有多个线程
- 属于同一个进程的线程共享该进程的所有资源,但是每个线程拥有自己独立的栈,不同的进程相互独立
- 线程之间切换代价小,进程间切换代价大
- 进程是程序的一次执行,线程是程序中的一段程序的执行
- 每个进程都有独立的内存空间,线程共享其所属进程的内存空间
多进程与多线程的区别
1.
多进程的数据是分开的(每个进程都有独立的内存空间),所以实现共享的时候比较麻烦需要进行进程间通信,同步简单。
多线程共享进程数据,共享简单,同步复杂。
进程/线程之间进行通信的方法:
1. 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
2. 互斥量:为协调共同对一个共享资源的单独访问而设计的。
3. 信号量:为控制一个具有有限数量用户资源而设计,它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
4. 事件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作2.
多进程占用内存多,切换复杂,CPU利用率低
多线程占用内存少,切换简单,CPU利用率高3.
多进程创建销毁切换复杂,速度慢
多线程创建销毁简单,速度快4.
多进程编程简单,调试简单
多线程编程复杂,调试复杂5.
可靠性:
多进程间不会互相影响
一个线程挂掉将导致整个进程挂掉6.
多进程适应于多核,多机分布,如果一台机器不够,扩展到多台机器比较简单
多线程适应于多核分布Summary
多进程的有点在于内存隔离,单个进程出现问题不会导致整个应用崩溃,缺点是进程间调用通讯和切换的开销较大,试用于目标自功能间的交互少
如果资源性能许可,设计由多个子应用程序来组合完成目标。
多线程的有点在于并行性,开销小,缺点是没有内存隔离,单个线程的崩溃会导致整个系统的崩溃。适用于存在大量IO,等需要和用户交互的场景,
使用多线程有利于提高系统的并行性和用户界面快速响应从而提高友好性。 -
进程 与 线程
2009-11-23 15:47:00进程与线程,很熟悉的名词,虽然写过多线程的程序,被问到了线程与进程,我竟然不知道线程是啥,进程又是啥。 整理下资料,方便以后查阅。。 进程:进程为应用程序的运行实例,是应用程序的一次动态执行。看似高深...进程与线程,很熟悉的名词,虽然写过多线程的程序,被问到了线程与进程,我竟然不知道线程是啥,进程又是啥。
整理下资料,方便以后查阅。。
进程:进程为应用程序的运行实例,是应用程序的一次动态执行。看似高深,我们可以简单地理解为:它是操作系统当前运行的执行程序。
进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:
1) 一个组成部分是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。
2) 另一个组成部分是地址空间,它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆栈分配空间。
进程是不活泼的。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,该线程负责执行包含在进程的地址空间中的代码。实际上,单个进程可能包含若干个线程,所有这些线程都“同时”执行进程地址空间中的代码。为此,每个线程都有它自己的一组CPU寄存器和它自己的堆栈。每个进程至少拥有一个线程,来执行进程的地址空间中的代码。如果没有线程来执行进程的地址空间中的代码,那么进程就没有存在的理由了,系统就将自动撤消该进程和它的地址空间。 若要使所有这些线程都能运行,操作系统就要为每个线程安排一定的CPU时间。它通过以一种循环方式为线程提供时间片(称为量程),从而造成一种假象,仿佛所有线程都是同时运行的一样。当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创建其他的线程,而这些线程又能创建更多的线程。线程:一个线程是给定的指令的序列 (你所编写的代码),一个栈(在给定的方法中定义的变量),以及一些共享数据(类一级的变量)。
每个线程有其自己的堆栈和程序计数器(PC)。你可以把程序计数器(PC)设想为用于跟踪线程正在执行的指令,而堆栈用于跟踪线程的上下文,上下文是当线程执行到某处时,当前的局部变量的值。虽然你可以编写出在线程之间传送数据的子程序,在正常情况下,一个线程不能访问另外一个线程的栈变量。
线程是比进程更小的处理模块。
区别:
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
-
进程与线程
2006-11-30 15:50:00进程与线程 在说进程和线程前,先说下程序的概念,程序就是为完成特定任务、用某种语言编写的一组指令的集合。指一段静态的代码。下面接着说进程和线程。记得在刚接触这两个概念时,是这样说的,进程是程序的一次...进程与线程
在说进程和线程前,先说下程序的概念,程序就是为完成特定任务、用某种语言编写的一组指令的集合。指一段静态的代码。下面接着说进程和线程。
记得在刚接触这两个概念时,是这样说的,进程是程序的一次执行过程,是系统进行调度和资源分配的一个独立单位。线程是指程序的一个指令执行序列,是比进程更小的执行单位。感觉那时学的一点也不明白。这几天看了写资料,整理了一下。感觉进程的概念这样定义较好,进程是可并发执行的程序在一个数据集合上的运行过程。这个也许较第一个有些抽象,但是包含的内容还是挺多的。
先用电脑系统上的一个例子形象的说明一下进程和线程:
简单的说,你每启动一个程序,就启动了一个进程。在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中*/
}
}
}