瀑布模型

瀑布模型核心思想是按工序将问题化简,将功能的实现与设计分开,便于分工协作,即采用结构化的分析与设计方法将逻辑实现与物理实现分开。将软件生命周期划分为可行性分析、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。

对于经常变化的项目而言,瀑布模型毫无价值

简述模型优缺点,简述其他模型如何弥补瀑布模型的不足

优点:阶段划分清晰,各阶段人员的职责明确,便于前后活动的衔接,有利于活动的重用和管理

缺点:缺乏灵活性,无法解决需求经常变化的问题

用其他弥补不足:

原型化模型:用于解决需求不明确的情况

螺旋模型:强调风险分析,特别适合庞大而复杂的、高风险的系统

 

进程和线程

1.对进程和线程的描述,一下()是正确的

  A 父进程的所有线程共享相同的地址空间,父进程的所有子进程共享相同的地址空间

  B 改变进程里面主线程的状态会影响其他线程的行为,改变父进程的状态不会影响其他子进程

  C 多线程会引起死锁,而多进程则不会

  D 以上都不对

D   进程拥有独立的地址空间,A错;多进程中父进程与子进程互不会影响,B错;多线程和多进程都会引起死锁,一般说起死锁指的都是进程间的死锁,C错。

 

 什么是进程(Process)和线程(Thread)

进程(Process)是应用程序的一次运行活动。从操作系统核心角度来说,进程是操作系统分配和调度系统内存资源、cpu时间片等资源的基本单位,为正在运行的应用程序提供

运行环境。

线程(Thread)是程序内部有并发性的顺序代码流。是cpu调度资源的最小单元。

单位大小

进程是操作系统分配和调度系统内存资源、cpu时间片 等资源的基本单位;一个进程至少包括一个线程。进程是操作系统资源管理的实体。
线程是cpu调度资源的最小单元。线程是进程的实体。


系统资源分配上

每个进程都有自己的内存地址空间。
线程没有自己独立的内存资源,它只有自己的执行堆栈和局部变量。但是在同属一个进程的多个线程中他们可以共享进程的内存

 

执行过程中

执行过程中,进程有内存单元的初始入口点,在存活阶段里拥有独立的地址空间。
进程是应用程序的一次运行活动,独立地执行;所以某一个进程崩溃以后,在保护模式下不会影响其他的进程,健壮性好。

每个已创建的进程都可以创建进程,创建进程的进程称为父进程,被创建的新进程为子进程,这样便形成一个进程树。

父进程与子进程可并行执行;父进程等 待子进程终止执行。父进程终止后,所有的子进程也都必须要终止。

而线程不能独立地执行,它必须依附在一个运行中的应用程序上。
但是,同一个进程中的多个线程可以并发地执行,并发性高,系统在数据交换上花费的资源少,运行效率高。

每个进程里都会有一个主线程,由它创建其他线程。

父进程为什么要创建子进程 

在程序设计时,某一个具体的功能模块可以通过函数或是线程等不同的形式来实现。对于同一进程而言,这些函数、线程都是存在于同一个地址空间下的,而且在执行时,大多只对与其相关的一些数据进行处理。如果算法存在某种错误,将有可能破坏与其同处一个地址空间的其他一些重要内容,这将造成比较严重的后果。为保护地址空间中的内容可以考虑将那些需要对地址空间中的数据进行访问的操作部分放到另外一个进程的地址空间中运行,并且只允许其访问原进程地址空间中的相关数据。

 

共同点
Process和Thread都有生命周期:
create 创建,ready就绪,running运行,waitSleepJoin阻塞,suspend挂起,stoped死亡

 

 

请阐述进程与线程的区别

解答:

  • ①从概念上:
    • 进程:一个程序对一个数据集的动态执行过程,是分配资源的基本单位。
    • 线程:一个进程内的基本调度单位。线程的划分尺度小于进程,一个进程包含一个或者更多的线程。
  • ②从执行过程中来看:
    • 进程:拥有独立的内存单元,而多个线程共享内存,从而提高了应用程序的运行效率。
    • 线程:每一个独立的线程,都有一个程序运行的入口、顺序执行序列、和程序的出口。但是线程不能够独立的执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • ③从逻辑角度来看(重要区别):
    • 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但是,操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理及资源分配。

 

进程通信方式有哪些?

进程间通讯的方式: 管道通讯,消息队列,信号量,共享内存,信号,套接字

解答:主要有以下6种:

  • 1、管道:管道是单向的、先进先出的、无结构的、固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。写进程在管道的尾端写入数据,读进程在管道的道端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样地,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。
    • 无名管道:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系(通常是指父子进程关系)的进程间使用。
    • 命名管道:命名管道也是半双工的通信方式,在文件系统中作为一个特殊的设备文件而存在,但是它允许无亲缘关系进程间的通信。当共享管道的进程执行完所有的I/O操作以后,命名管道将继续保存在文件系统中以便以后使用。
  • 2、信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其它进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 3、消息队列:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 4、信号:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
  • 5、共享内存:共享内存就是映射一段能被其它进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其它进程间通信方式运行效率低而专门设计的。它往往与其它通信机制(如信号量)配合使用,来实现进程间的同步和通信。
  • 6、套接字:套接字也是一种进程间通信机制,与其它通信机制不同的是,它可用于不同机器间的进程通信。

几种方式的比较:

  • 管道:速度慢,容量有限
  • 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
  • 信号量:不能传递复杂消息,只能用来同步
  • 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了一块内存的。

 

同步的方式有哪些?

线程同步指多个线程同时访问某资源时,采用一系列的机制以保证同时最多只能一个线程访问该资源。线程同步是多线程中必须考虑和解决的问题,因为很可能发生多个线程同时访问(主要是写操作)同一资源,如果不进行线程同步,很可能会引起数据混乱,造成线程死锁等问题;

线程同步的方式:临界区,互斥对象机制,信号量对象,事件信号

  • 临界区:通过对多线程的串行化来访问公共资源或者一段代码,速度快,适合控制数据访问
  • 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以可以保证公共资源不会同时被多个线程访问
  • 信号量:它允许多个线程同一时刻访问同一资源,但是需要限制同一时刻访问此资源的最大线程数目。信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中PV操作相似。
  • 事件(信号):通过通知操作的方式来保持多线程的同步,还可以方便的实现多线程的优先级比较的操作

总结比较: 

  • 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。
  • 互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。
  • 通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器

 

说出你所知道的保持进程同步的方法?

  进程间同步的主要方法有原子操作、信号量机制、自旋锁、管程、会合、分布式系统等。

 

线程安全

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。

 

什么是死锁?其条件是什么?怎样避免死锁?

首先回答死锁的定义,所谓死锁就是一个进程集合中的多个进程因为竞争资源,而造成的互相等待现象。

死锁的原因:系统资源不足;多个进程的推进顺序不合理

死锁的必要条件:

  • 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
  • 请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
  • 非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
  • 循环等待条件(Circular wait):系统中若干进程组成环路,改环路中每个进程都在等待相邻进程正占用的资源。

处理死锁的策略:

  • 鸵鸟策略。忽略该问题。例如鸵鸟算法,该算法可以应用在极少发生死锁的情况下。传说中,鸵鸟看到危险就把头深埋地下,这是显然是一种很消极的策略。
  • 检测与恢复策略。检测死锁并且恢复。
  • 避免策略。仔细地对资源进行动态分配,以避免死锁。
  • 预防策略。通过破坏死锁的必要条件,来防止死锁的产生。

 

解除死锁,银行家算法:http://blog.csdn.net/abigale1011/article/details/6450845/

 

银行家算法

银行家算法( banker's algorithm )由 Dijkstra(1065)提出。他将死锁的问题演示为一个银行家贷款的模型。
一个银行家向一群客户发放信用卡,每个客户有不同的信用额度。每个客户可以提出信用额度内的任意额度的请求,直到额度用完后再一次性还款。银行家承诺每个客户最终都能获得自己需要的额度。
所谓“最终”,是说银行家可以先挂起某个额度请求较大的客户的请求,优先满足小额度的请求,等小额度的请求还款后,再处理挂起的请求。这样,资金能够永远流通。

银行家算法其核心是:保证自己的限额至少不小于一个客户的限额。
我们可以用填表法来快速解决银行家算法。

建立一个二维表格:每列数据表示每次交易各个参与者的限额。这个表格第一列数据是银行家是客户的交易限额,每发生一次交易,增加一列,同时将银行家和发生交易的客户的限额减小。直到银行家的限额小于某个客户的限额时,交易不能继续进行。否则便发生死锁。

例题:
1、操作系统分配资源时的一个重要考虑是避免死锁的发生.若系统中有同类资源 16 个,由四个进程 P1、P2、P3 和 P4 共享该资源。已知 P1、P2、P3、P4 所需的资源总数分别为 8、5、9、6。各进程请求资源的次序如下表,若系统采用银行家算法为它们分配资源,那么_(1)__依次申请分配会使系统进入不安全状态。 
进程申请资源的情况

序号 进程 申请量 
1 P1 6 
2 P2 4 
3 P3 5 
4 P4 1 
5 P1 1 
6 P2 1 
A.3、4 B.3、5 C.4、5 D.5、6

答案是c
我们初始化一个二维表格


到完成第三个请求到达的时候,资源只有一个了。此时只能满足p2的请求。所以,第四个和第五个请求会被系统挂起。第六个请求p2到达后会被处理。等p2事务结束释放资源后,系统会再处理挂起的请求,这样就不会发生死锁。一旦在第三步后将剩下的唯一的一个资源分配给其它的进程,(如请求4或请求5),则请求4和5可能会因需要不止一个资源而继续等待,则发生了死锁。(通过表格可以看出,依次申请到C组时,银行家的剩余额度已经不能满足所有的客户的需求了)

 

描述实时系统的基本特性

  在特定时间内完成特定的任务,实时性与可靠性。

  所谓“实时操作系统”,实际上是指操作系统工作时,其各种资源可以根据需要随时进行动态分配。由于各种资源可以进行动态分配,因此,其处理事务的能力较强、速度较快。

 

中断和轮询的特点

  对I/O设备的程序轮询的方式,是早期的计算机系统对I/O设备的一种管理方式。它定时对各种设备轮流询问一遍有无处理要求。轮流询问之后,有要求的,则加以处理。在处理I/O设备的要求之后,处理机返回继续工作。尽管轮询需要时间,但轮询要比I/O设备的速度要快得多,所以一般不会发生不能及时处理的问题。当然,再快的处理机,能处理的输入输出设备的数量也是有一定限度的。而且,程序轮询毕竟占据了CPU相当一部分处理时间,因此,程序轮询是一种效率较低的方式,在现代计算机系统中已很少应用。

  中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。

  轮询——效率低,等待时间很长,CPU利用率不高。

  中断——容易遗漏一些问题,CPU利用率高。

 

什么是临界区?如何解决冲突?

  每个进程中访问临界资源的那段程序称为临界区,每次只准许一个进程进入临界区,进入后不允许其他进程进入。

  (1)如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入;

  (2)任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待;

  (3)进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区;

  (4)如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

 

你知道操作系统的内容分为几块吗?什么叫做虚拟内存?他和主存的关系如何?内存管理属于操作系统的内容吗?

  操作系统的主要组成部分:进程和线程的管理,存储管理,设备管理,文件管理。虚拟内存是一些系统页文件,存放在磁盘上,每个系统页文件大小为4K,物理内存也被分页,每个页大小也为4K,这样虚拟页文件和物理内存页就可以对应,实际上虚拟内存就是用于物理内存的临时存放的磁盘空间。页文件就是内存页,物理内存中每页叫物理页,磁盘上的页文件叫虚拟页,物理页+虚拟页就是系统所有使用的页文件的总和。

 

说说分段和分页

  页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。

  段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需要。

  页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。

  分页的作业地址空间是一维的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

 

Linux中常用到的命令

  显示文件目录命令ls        如ls

  改变当前目录命令cd        如cd /home

  建立子目录mkdir           如mkdir xiong

  删除子目录命令rmdir       如rmdir /mnt/cdrom

  删除文件命令rm            如rm /ucdos.bat

  文件复制命令cp            如cp /ucdos /fox

  获取帮助信息命令man      如man ls

  显示文件的内容less        如less mwm.lx

  重定向与管道type          如type readme>>direct,将文件readme的内容追加到文direct中

 

Linux文件属性有哪些?(共十位)

  -rw-r--r--那个是权限符号,总共是- --- --- ---这几个位。

  第一个短横处是文件类型识别符:-表示普通文件;c表示字符设备(character);b表示块设备(block);d表示目录(directory);l表示链接文件(link);后面第一个三个连续的短横是用户权限位(User),第二个三个连续短横是组权限位(Group),第三个三个连续短横是其他权限位(Other)。每个权限位有三个权限,r(读权限),w(写权限),x(执行权限)。如果每个权限位都有权限存在,那么满权限的情况就是:-rwxrwxrwx;权限为空的情况就是- --- --- ---。

  权限的设定可以用chmod命令,其格式位:chmod ugoa+/-/=rwx filename/directory。例如:

  一个文件aaa具有完全空的权限- --- --- ---。

  chmod u+rw aaa(给用户权限位设置读写权限,其权限表示为:- rw- --- ---)

  chmod g+r aaa(给组设置权限为可读,其权限表示为:- --- r-- ---)

  chmod ugo+rw aaa(给用户,组,其它用户或组设置权限为读写,权限表示为:- rw- rw- rw-)

  如果aaa具有满权限- rwx rwx rwx。

  chmod u-x aaa(去掉用户可执行权限,权限表示为:- rw- rwx rwx)

  如果要给aaa赋予制定权限- rwx r-x r-x,命令为:

  chmod u=rwx,go=rx aaa

 

makefile文件的作用是什么?

  一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中。makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”。一旦写好,只需要一个make命令,整个工程完全自动编译,极大地提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具。一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

 

什么是缓冲区溢出?有什么危害?其原因是什么?

  缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。

  危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。

  造成缓冲区溢出的主原因是程序中没有仔细检查用户输入的参数

 

操作系统进程调度算法

http://blog.csdn.net/luyafei_89430/article/details/12971171

一、先来先服务和短作业(进程)优先调度算法
1.先来先服务调度算法
2.短作业(进程)优先调度算法


二、高优先权优先调度算法
1.优先权调度算法,包括非抢占式优先权算法、抢占式优先权调度算法(强调系统的实时性,实时比较优先级)
2.高响应比优先调度算法,优先权=(等待时间+要求服务时间)/要求服务时间
(1) 如果作业的等待时间相同,则要求服务的时间愈短,其优先权愈高,因而该算法有利于短作业。
(2) 当要求服务的时间相同时,作业的优先权决定于其等待时间,等待时间愈长,其优先权愈高,因而它实现的是先来先服务。
(3) 对于长作业,作业的优先级可以随等待时间的增加而提高,当其等待时间足够长时,其优先级便可升到很高,从而也可获得处理机。简言之,该算法既照顾了短作业,又考虑了作业到达的先后次序,不会使长作业长期得不到服务。因此,该算法实现了一种较好的折衷。当然,在利用该算法时,每要进行调度之前,都须先做响应比的计算,这会增加系统开销。


三、基于时间片的轮转调度算法
1.时间片轮转法
2.多级反馈队列调度算法,
多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。
(1) 应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。例如,第二个队列的时间片要比第一个队列的时间片长一倍,……,第i+1个队列的时间片要比第i个队列的时间片长一倍。
(2) 当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n 队列便采取按时间片轮转的方式运行。
(3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。如果处理机正在第i队列中为某进程服务时,又有新进程进入优先权较高的队列(第1~(i-1)中的任何一个队列),则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回到第i队列的末尾,把处理机分配给新到的高优先权进程。

 

服务器线程优化问题?

线程是轻量级的,它自己不拥有系统资源,但是我们知道线程执行时候是可以操作硬盘的文件,也可以操作内存的数据,那么这些被线程操作的资源从哪里来的呢?

答案:线程用的进程的资源

 

线程的特点:

  • 特点一:线程是进程的一个实体,也就是说线程的母体是进程,这是线程的范畴问题。
  • 特点二:线程是轻量级的,它自己不拥有系统资源,但是我们知道线程执行时候是可以操作硬盘的文件,也可以操作内存的数据,那么这些被线程操作的资源从哪里来的呢?上面的解释里回答了这个问题,那就是线程可以共享进程的资源,换句话说线程操作的资源是进程的资源。
  • 特点三:线程自己也有寄存器和堆栈,这些东西本身也是可以存储数据的,数据也是要占用系统的部分资源,那么这个解释也就说明,线程本身也是可以占一定系统资源了,只不过这个资源比较少而已,所以这个解释就补充了特点二的场景:线程操作的资源除了它所在进程的资源外还有它自身能控制的资源,这一点比较重要,我会在后面讲线程安全问题里提到线程自有资源的使用问题的。

 

线程的运作流程: 线程创建 线程执行 线程销毁

 

我们就会发现线程的创建过程和线程的销毁过程其实是和处理请求的逻辑无关,但是一个线程又必须经历这三个阶段,因此线程创建的时间和线程销毁的时间也会被统计到请求处理时间里,那么我们就会想有没有办法可以消除线程创建和销毁所花的时间对请求处理的影响呢?目标就是减少线程创建和销毁的时间

 

我们希望请求处理流程只是作用在线程执行这块,那么在实际的生产实践里我们又是如何来解决这个问题了?解决方案就是使用线程池技术,线程池技术就是基于线程创建和销毁操作影响性能的角度来设计的,不过线程池技术并非简单的事先创建好一批线程,然后统一销毁一批线程那么简单.  

 举例分析JDK的线程池

JDK的线程池对线程池的大小设定了两个参数,一个是核心线程个数,一个是最大线程个数

  1. 1.    系统启动时,核心线程就会被创建
  2. 2.    当用户请求没有超过核心线程的处理能力时,新的线程不再创建
  3. 3.    当用户请求超过核心线程的处理能力时,新的线程创建,使用完毕后不是立即被销毁,也会被收到线程池里面,当线程池里的总数超过最大线程个数时,线程不再被创建

(线程数量根据实际请求情况,这样充分利用了计算机资源, 又避免了资源浪费)

  1. 4.    超时机制。当超出核心线程的线程在一定时间内未被使用,那么这些线程将会被销毁,资源会被释放。

(使得线程池里线程的数量在一个合理的范围内)

5    队列机制。对处理不过来的请求排队等待,当某个线程处理完毕时,该线程会从这个队列里面取出一个请求进行处理

      (避免请求的丢失)

6    拒绝策略。如果队列容量超出了计算机的处理能力,队列会抛弃无法处理的请求。

7….JDK还有很多队列策略

 

由上面对JDK自带线程池的介绍,我们发现使用线程池我们要考虑如下的问题,具体如下:

  • 问题一:线程池初始化的时候我们到底要事先创建多少个线程放在池子里比较合适。
  • 问题二:线程池初始化时候如果创建的线程过多会有什么问题。
  • 问题三:一台服务器由于受限于自身能力的限制例如CPU的能力,内存的能力等等,那么一台服务器可以创建多少个有效线程的数量其实是有个临界值的,那么当业务方要求创建超出临界值的线程时候我们的处理策略是怎样的呢。

问题三的我在介绍JDK里线程池的设计方案时候已经提到了,解决方法就是当业务方要求超出临界值时候,具体就是超出线程池最大线程数的时候,我们用一个队列先缓存这些请求,等线程池里的线程空闲出来后,再去从队列里取出业务请求交付给线程进行处理。

至于问题一和问题二,这个就和多线程的技术相关了,为了更好的解答它,我这里先来介绍下多线程技术。

计算机多线程的时间片问题:

有一个线程被分配到的时间片长度是10毫秒,如果这个线程没有其他干扰,它执行完毕需要花费50毫秒,那就等于要执行5次时间片,假如我们再新增了一个线程,该线程时间片也是10毫秒,也要执行50毫秒才能执行完毕,那么其中一个线程执行完一次时间片,按照轮询机制另外一个线程也要被执行,最后我们就会发现第一个线程执行时间就变成了100毫秒,如果我们再加上CPU的调度所花的时间,该线程的执行时间就会远远大于100毫秒,虽然100多毫秒人的感官是很难觉察到,但是这个做法毕竟让单个线程的执行效率大幅度降低了,如果我们线程开启的更多,那么单个线程执行效率也就会变得更低。

有了这个结论我们再去看看线程池问题一和问题二,如果我们一开始创建了太多线程,而且这些线程大部分都会被闲置,那么这些闲置的线程就会让有效线程的执行效率大大降低,同时闲置的线程还会消耗系统资源,而这些被消耗的系统资源都没有用到业务处理上,所以成熟的线程池方案就会设计核心线程和最大线程的概念,它们可以让线程池根据实际业务需求和系统负载能力做到动态调节,这样就可以减少开启更多线程影响线程执行效率的问题,也可以让计算机的系统资源得到更加有效的利用。

C10K的目标

业界有一个C10K的目标,所谓c10k问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent 10 000 connection(这也是c10k这个名字的由来)。

一般Apache最多支持5000个客户端的并发请求,而且不会随着服务器硬件配置的提升有质的改变,而且单个请求的处理能力会下降

而ngnix可以做到3万个并发,而且可以随服务器配置提升而提升

ngnix的设计

Nginx开发从入门到精通http://tengine.taobao.org/book/#nginx

nginx源码分析--master和worker进程模型

http://blog.csdn.net/yusiguyuan/article/details/40924415?utm_source=tuicool

《深入理解Nginx》-陶辉

阿里集团数据平台博客

阿里集团数据平台博客2

http://blog.csdn.net/lengzijian/article/details/7349673

 

nginx模块的开发门槛还挺高,需要开发者对于服务器的非阻塞调用、事件模型有较深的理解,而如果请求处理时需要有全局化视角时,麻烦的多进程通信又来了,开发者不能使用简单的堆分配对象,而要使用nginx_slab管理内存。

 

 

 

 

 

 

 

posted on 2015-03-27 10:24  kylehz  阅读(691)  评论(0)    收藏  举报