线程(二)

用户级线程 User Threads

  • 线程管理(创建、资源申请、调度、通信等)
    由user-level threads library “一手包办”,不靠OS内核
  • 举例:Thread primary thread libraries
    • JAVA threads
    • POSIX pthreads
    • Win32 threads

内核级线程 Kernel Threads

  • 线程管理由操作系统内核的kernel-level threads实现
  • 举例
    • Windows XP/2000
    • Solaris

用户线程要受内核支持,无需内核管理,而内核线程由操作系统直接支持和管理。
有些操作系统内核支持多线程,有些不支持(早期的一些)。有不同的模型。

多线程模型 Multithreading

  • Many-to-One(OS不支持内核线程,程序包(在用户态)比如JAVA threads library对操作系统来说就是个单独的进程,程序包得到操作系统给的CPU,由这个包对多个线程做二次分配)
    一个出错,其他线程都会受连累,交出CPU
  • One-to-One(OS内核支持多线程,一个用户态线程对应一个内核线程)
    出错线程没有影响其它正常线程
  • Many-to-Many(用户态有M个线程,内核态有N个线程)
  • Two-level (包括Many-to-Many和One-to-One)

线程管理相对于进程管理带来的问题

  • fork()操作和exec()操作的意义有变
    之前了解了进程中的fork,子进程继承了父进程的所有资源。线程里面的fork语义有什么变化?一个线程调用fork,仅仅复制调用线程呢?还是复制与调用线程同属于一个task的所有线程呢?这各有道理。
    而exec()是一样的,exec()在进程中是子进程替换代码段,装入二进制文件并执行。那在线程里面,这里的代码段数据段是共享的,这样按照原来的exec()是不是影响到别的线程了?还是说只替换属于这个线程独立部分的代码?这也各有各的道理所在。
    都是操作系统线程管理中需要处理的具体问题,都要明确给出答案。

  • 撤销线程
    在线程正常完成操作前,终止它,释放各种资源。至少有两种语义,马上撤销和不断检查它是否应该终止,检查到应该终止时候,才终止自己。

  • 信号处理
    进程与进程之间,通信就是进程整体处理,多线程情况下,信号发过来,哪个线程去响应?

  • 线程池 Thread pools
    如果每次开一个线程就要创建一个线程处理请求,用完之后就会丢弃,这样在有大量高并发的情况下,无限制的线程会耗尽系统资源,解决方案是使用线程池。
    在进程开始时创建一定数量的线程,并放入到池中等待工作。服务器收到请求时候,会唤醒池中的一个线程(如果有可用的线程),并将要处理的请求传递给它。一旦线程完成服务,它就会返回池中再等待工作。
    这样有两个优点:

    • 使用现有的线程处理请求比等待创建新的线程要快
    • 线程池限制了在任何时候可用线程的数量

你可能感兴趣的:(线程(二))