进程与线程

參考: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. MVC—WebAPI(调用、授权)

    ASP.NET MVC—WebAPI(调用.授权)   本系列目录:ASP.NET MVC4入门到精通系列目录汇总 微软有了Webservice和WCF,为什么还要有WebAPI? 用过WCF的人应该 ...

  2. dba_dependencies查询结果视图

    [oracle@rhel63single ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Fri Mar 13 0 ...

  3. 网络的基本概念TCP, UDP, 单播(Unicast), 多播(多播)(Multicast)

    章相当低级,但相当重要! 我们周围一切差点儿都依赖于把事情抽象成低等级,并在某一点把它详细化,在一些设计概念中.接口层十分清晰而且目标非常集中,应用程序不用考虑操作系统怎样工作,操作系统也不用考虑硬件 ...

  4. error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述

    错误: 1>WinMain.obj : error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述 1> ...

  5. C++实现链表

    最后几天留在Intel,没什么事情,都是开开会.趁着闲功夫,把数据结构复习一下,写了一个list.时间仓促,有些地方考虑的可能没那么到位,望高手们指点. #include <iostream&g ...

  6. PKU 1509 Glass Beads (最小表示法)

    题意:有一个环形字符串,让你找一个位置切一刀使得字符串字母序最小.输出这个位置. 思路:能够看成两个字符串比較.一个是从下标0開始(0~n-1),一个从下标1開始(1~n-1,0). 然后两个指针i= ...

  7. Oracle to_char,to_date

    一.在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式,我们可以使用oracle提供的to_date函数. sql语句为: SELECT to_date(' ...

  8. CSDN博客ByeBye

    情绪csdn定制博客博客是不够的,没有足够的光.对于我这种极简的人,不合适. 我们不打算更新的博客. 至http://blog.edagarli.com/ 版权声明:本文博主原创文章.博客,未经同意不 ...

  9. 写你自己 android 多通道打包工具 可以包libs和.so文件

    android上传应用程序,需要区分各个信道. 通常更改配置文件中的一个通道id,假设有多个通道,手动更改并生成apk这将是非常麻烦的,及增加误差的概率. 在这个课堂上分享一个打包工具.也可在网上类似 ...

  10. ElasticSearch实战

    ElasticSearch实战-入门 1.概述 今天接着<ElasticSearch实战-日志监控平台>一文来给大家分享后续的学习,在<ElasticSearch实战-日志监控平台& ...