进程与线程

參考:http://www.cnblogs.com/blueclue/archive/2010/07/16/1778855.html

首先比較Linux进程和线程的创建的差别,以此展开:

创建进程:(1)调用fork(),为子进程新建内核栈、pthread_info和task_struct,复制父进程的大部分的參数,採用写时复制(copy-on-write)辅助父进程的资源,改动子进程如pid、ppid等重要资源。(2)调用exec()为子进程分配地址空间,加载运行程序。

创建线程:与进程创建没有大的差别,唯一不同的就是,在调用clone()的fork()參数表里指明共享的资源。

标志                    含义

  CLONE_PARENT   创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”

  CLONE_FS           子进程与父进程共享同样的文件系统,包含root、当前文件夹、umask

  CLONE_FILES      子进程与父进程共享同样的文件描写叙述符(file descriptor)表

  CLONE_NEWNS   在新的namespace启动子进程,namespace描写叙述了进程的文件hierarchy

  CLONE_SIGHAND   子进程与父进程共享同样的信号处理(signal handler)表

  CLONE_PTRACE   若父进程被trace,子进程也被trace

  CLONE_VFORK     父进程被挂起,直至子进程释放虚拟内存资源

  CLONE_VM           子进程与父进程执行于同样的内存空间

  CLONE_PID          子进程在创建时PID与父进程一致

  CLONE_THREAD    Linux 2.4中添加以支持POSIX线程标准,子进程与父进程共享同样的线程群

为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是由于,线程共享同样的内存空间。不同的线程能够存取内存中的同一个变量。所以,程序中的全部线程都能够读或写声明过的全局变量。假设曾用fork() 编写过重要代码,就会认识到这个工具的重要性。为什么呢?尽管fork() 同意创建多个进程,但它还会带来下面通信问题:怎样让多个进程相互通信,这里每一个进程都有各自独立的内存空间。对这个问题没有一个简单的答案。尽管有很多不同种类的本地IPC (进程间通信),但它们都遇到两个重要障碍:

  • 强加了某种形式的额外内核开销,从而减少性能。
  • 对于大多数情形,IPC不是对于代码的“自然”扩展。通常极大地添加了程序的复杂性。

双重坏事: 开销和复杂性都非好事。假设以前为了支持 IPC而对程序大动干戈过,那么您就会真正赞赏线程提供的简单共享内存机制。因为全部的线程都驻留在同一内存空间,POSIX线程无需进行开销大而复杂的长距离调用。仅仅要利用简单的同步机制,程序中全部的线程都能够读取和改动已有的数据结构。而无需将数据经由文件描写叙述符转储或挤入紧窄的共享内存空间。仅此一个原因,就足以让您考虑应该採用单进程/多线程模式而非多进程/单线程模式。

为什么要用线程?

与标准 fork()相比,线程带来的开销非常小。内核无需单独复制进程的内存空间或文件描写叙述符等等。这就节省了大量的CPU时间,使得线程创建比新进程创建快上十到一百倍。由于这一点,能够大量使用线程而无需太过于操心带来的CPU 或内存不足。使用 fork() 时导致的大量 CPU占用也不复存在。这表示仅仅要在程序中有意义,通常就能够创建线程。

当然,和进程一样,线程将利用多CPU。假设软件是针对多处理器系统设计的,这就真的是一大特性(假设软件是开放源代码,则终于可能在不少平台上执行)。特定类型线程程序(尤其是CPU密集型程序)的性能将随系统中处理器的数目差点儿线性地提高。假设正在编写CPU很密集型的程序,则绝对想设法在代码中使用多线程。一旦掌握了线程编码,无需使用繁琐的IPC和其他复杂的通信机制,就行以全新和创造性的方法解决编码难题。全部这些特性配合在一起使得多线程编程更有趣、高速和灵活。

什么是线程?

  • 专业点的说法,线程被定义为一个独立的指令流,它本身的运转由操作系统来安排,可是,这意味着什么呢?
  • 对软件开发人员来说,解释线程最好的描写叙述就是“procedure”能够独立于主程序执行。
  • 再进一步,设想一个包括了大量procedure的主程序,然后想象全部这些procedure在操作系统的安排下一起或者独立的执行,这就是对于多线程程序的一个简单描写叙述。
  • 问题是,它是怎样实现的呢?
  • 在弄懂线程之前,第一步要搞清楚Unix进程。进程被操作系统创建,并须要相当多的“开支”,进程包括例如以下程序资源和程序执行状态信息:
  1. 进程ID,进程群组ID,用户ID,群组ID
  2. 环境
  3. 工作文件夹
  4. 程序指令
  5. 寄存器
  6. 文件描写叙述符
  7. 信号动作
  8. 共享库
  9. 进程间通信工具(比如消息队列,管道,信号量,共享内存)

Unix进程                                                            Unix进程内部的线程

  • 线程使用和在进程内的生存,仍由操作系统来安排而且独立的实体来执行,非常大程度上是由于它们为可执行代码的存在复制了刚刚好的基本资源。
  • 这个独立的控制流之所以能够实现,是由于线程维护着例如以下的东西:
  1. 栈指针
  2. 寄存器
  3. 调度属性(比如规则和优先级)
  4. 等待序列和堵塞信号
  5. 线程拥有的数据
  • 所以,总的来说,Unix环境里的线程有例如以下特点:
  1. 它生存在进程中,并使用进程资源;
  2. 拥有它自己独立的控制流,前提是只要它的父进程还存在,而且OS支持它;
  3. 它只复制能够使它自己调度的必要的资源;
  4. 它可能会同其他与之同等独立的线程分享进程资源;
  5. 假设父进程死掉那么它也会死掉——或者类似的事情;
  6. 它是轻量级的,由于大部分的开支已经在它的进程创建时完毕了。
  • 由于在同一进程内的线程分享资源,所以:
  1. 一个线程对共享的系统资源做出的改变(比如关闭一个文件)会被全部的其他线程看到;
  2. 指向同一地址的两个指针的数据是同样的;
  3. 对同一块内存进行读写操作是可行的,但须要程序猿作明白的同步处理操作。

Linux进程和线程的比較的更多相关文章

  1. Linux进程或线程绑定到CPU

    Linux进程或线程绑定到CPU 为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程. 进程绑定到CPU Linux提供一个接口,可以将进程 ...

  2. Linux 进程、线程运行在指定CPU核上

    /******************************************************************************** * Linux 进程.线程运行在指定 ...

  3. linux进程、线程与cpu的亲和性(affinity)

    参考:http://www.cnblogs.com/wenqiang/p/6049978.html 最近的工作中对性能的要求比较高,下面简单做一下总结: 一.什么是cpu亲和性(affinity) C ...

  4. Linux进程与线程的区别

    进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...

  5. linux进程与线程的区别【转】

    知乎上总结: "linux使用的1:1的线程模型,在内核中是不区分线程和进程的,都是可运行的任务而已.fork调用clone(最少的共享),pthread_create也是调用clone(最 ...

  6. Linux进程和线程

    一.进程产生的方式 1.描述进程的ID号通常叫做PID,即进程ID,PID的变量类型为pid_t. 2.getpid(void)返回当前进程的ID号,getppid(void)返回当前进程的父进程的I ...

  7. Linux -- 进程或线程独占CPU

    如果想让特定进程或线程独占某一或某些CPU,我们需要做三件事. 一,隔离CPU,避免其它线程run在被隔离的CPU上. 二,绑定所有的interrupts到非隔离的CPU上,避免被隔离的CPU收到in ...

  8. 操作系统:Linux进程与线程

    这里是一部分内容,还会做修改. 一:目的及内容 学习fork(),exec,pthread库函数的使用,阅读源码,分析fork,exec,pthread_create函数的机理 代码实现: 进程A创建 ...

  9. linux --> 进程和线程

    进程和线程 进程(process)和线程(thread)是操作系统的基本概念,下面用一个类比,来解释它们. 1. 计算机的核心是CPU,它承担了所有的计算任务.它就像一座工厂,时刻在运行. 2. 假定 ...

随机推荐

  1. MINA2 源代码学习--源代码结构梳理

    一.mina总体框架与案例: 1.总体结构图: 简述:以上是一张来自网上比較经典的图,总体上揭示了mina的结构,当中IoService包括clientIoConnector和服务端IoAccepto ...

  2. 图片切割工具---产生多个div切割图片 采用for和一的二维阵列设置背景位置

    照片库 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21vZ2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  3. oracle设备

    # Oracle Environment export ORACLE_BASE=/opt/oracle export ORACLE_HOME=/opt/oracle/product/11gR2/db ...

  4. JavaIO流程--创建文件和目录的实例

    *创建函数:  *public boolean createNewFile():创建文件 本文假设存在.不创造(转让file.createNewFile()返回false)  *public bool ...

  5. python 性能- and-or 学习技能

    C语言类似表情: bool ? a : b ,当表达式值为真的话,值为a.否则为b. 看一个样例: >>> a = "first" >>> b ...

  6. POJ 3414--Pots(BFS+回溯路径)

    Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9963   Accepted: 4179   Special Ju ...

  7. 自己写CPU第五级(4)——逻辑、实现移动和空指令

    我们会继续上传新书<自己写CPU>(未公布).今天是18片,我每星期试试4 5.5 改动OpenMIPS以实现逻辑.移位操作与空指令 为了实现逻辑.移位操作与空指令(当中nop.ssnop ...

  8. RH253读书笔记(6)-Lab 6 Implementing Web(HTTP) Services

    Lab 6 Implementing Web(HTTP) Services Goal: To implement a Web(HTTP) server with a virtual host and ...

  9. DDD事件总线

    DDD事件总线 基本思路: (1)       在事件总线内部维护着一个事件与事件处理程序相映射的字典. (2)       利用反射,事件总线会将实现了IEventHandler的处理程序与相应事件 ...

  10. WPF学习(5)依赖属性

    今天我们来学习WPF一个比较重要的概念:依赖属性.这里推荐大家看看周永恒大哥的文章,讲的确实很不错.我理解的没那么深入,只能发表一下自己的浅见.提到依赖属性,不得不说我们经常使用的传统的.net属性, ...