深入理解linux内核之(二)进程

                                      深入理解linux内核之(二)进程

      程序是静态的,进程是正在执行的程序的一个实例,一个程序可以由多个进程组成.进程是资源分配的实体.
在进程被创建出来之后,该子进程几乎和父进程一样.子进程复制了父进程的地址空间,从fork()之后的第一条指令开始执行,和父进程有同样的程序可执行代码(exec调用除外).尽管子进程和父进程具有同样的程序执行代码,但是子进程拥有自己的stack和heap,因此,子进程对数据的修改对父进程来说是不可见的.
前面说到子进程复制了父进程的地址空间以及数据.那么,这种复制遵循 写时复制(COW)  的原则.当子进程创建之后,内核将父进程的数据标记为read-only只读.一开始子进程是共享父进程的数据的,只有当子进程需要对数据作出修改(写)的时候,才会将相关数据从父进程复制到子进程的地址空间.

尽管如此,在用户空间子进程还是从父进程继承了很多东西:

  •     父进程打开的文件,包括文件描述符,offset
  •     Real user ID, real group ID, effective ID, effective group ID
  •     追加的group ID
  •     进程组ID
  •     Session 会话ID
  •     控制终端
  •     Set-user-ID, set-group-ID 标志
  •     当前的工作目录
  •     Root 目录
  •     创建文件的模式掩码

指的是创建一个文件时,给文件的最基本的权限.比如055.

  •     信号mask以及信号的处理方式(handle)

子进程拥有和父进程相同的信号处理方式.例如父进程忽略了SIGINT,子进程也 了SIGINT信号,当然,子进程可以更改该处理方式.

  •     打开文件的close-on-exec标志
  •     环境变量
  •     共享内存段
  •     内存映射
  •     资源限制变量

子进程和父进程不同之处:

  •     fork()的返回值不同

fork()在父进程中返回子进程进程号,在子进程中返回0;

  •     进程号不同
  •     父进程ID不同
  •     父进程的文件锁没有被子进程继承
  •     挂起的闹钟被清除
  •     信号集被设置为空

新版本的Linux(2.6)内核中,已经能够很好的对多线程进行支持了, 在较老版本的Linux当中,将线程当做普通进程或者交付给用户空间处理线程.对于现行的新Linux版本提出了一个轻量级进程的概念.内核中,用一个轻量级的进程代表一个线程,并将用户空间的线程和内核中的轻量级进程进行关联,从而可以使得用户空间线程得到管理和调度.轻量级进程共享父进程的数据.这样一来,可以达到很好的对多线程进行支持.
每一个进程在内核中都有一个task_struct结构体来表示,该结构体包含了一个进程所需的全部信息.并将这些task_struct放到一个双向链表task list中.
关于task_struct相关结构我在这里就不赘述,这方面的资料参考Linux Kernel development

 

 



版权申明:
转载文章请注明原文出处http://blog.csdn.net/feiyinzilgd/archive/2010/09/15/5885640.aspx
并请联系谭海燕本人或者前往谭海燕个人主页留言

时间: 2025-01-19 17:41:58

深入理解linux内核之(二)进程的相关文章

Linux内核剖析 之 进程简介

1.概念    1.1  什么是进程?     进程是程序执行的一个实例,可以看作充分描述程序已经执行到何种程度的数据结构的汇集.     从内核观点看,进程的目的就是担当分配系统资源(CPU时间,内存等)的实体.     我们熟悉的fork()库函数,它有两种用法:     (1).一个父进程希望复制自己,使父子进程执行不同的代码段,常用于网络服务程序.     (2).一个进程要执行一个不同的程序,fork()后立即exec(),如shell. 1.2  什么是线程?     有时候,一个进

深入理解PHP内核(二)之SAPI探究_php实例

在上篇文章给大家介绍了深入了解PHP内核(一),相信大家通过本文多多少少都学到些知识吧,关于php内核知识继续关注本篇文章. SAPI是Server Application Programming Interface(服务器应用编程接口)的缩写.PHP通过SAPI提供了一组接口,供应用和PHP内核之间进行数据交互. 简单的讲,就像函数的输入和输出一样,我们通过Linux命令行执行一段PHP代码,本质是Linux的Shell通过PHP的SAPI传入一组参数,Zend引擎执行后,返回给shell,由

浅谈Linux内核创建新进程的全过程_Linux

进程描述 进程描述符(task_struct) 用来描述进程的数据结构,可以理解为进程的属性.比如进程的状态.进程的标识(PID)等,都被封装在了进程描述符这个数据结构中,该数据结构被定义为task_struct 进程控制块(PCB) 是操作系统核心中一种数据结构,主要表示进程状态. 进程状态 fork() fork()在父.子进程各返回一次.在父进程中返回子进程的 pid,在子进程中返回0. fork一个子进程的代码   #include <stdio.h> #include <std

Linux内核剖析 之 进程地址空间(一)

绪论     内核获取内存方式--直接了当:     1. 从分区页框分配器获取内存(__get_free_pages()或alloc_pages()):     2. 使用slab分配器为专用或通用对象分配内存(kmem_cache_alloc()或kmalloc()):     3. 使用vmalloc或vmalloc_32获取一块非连续内存区.     如果申请的内存得以满足,这些函数返回一个页描述符地址或线性地址.     *内核申请内存使用这些简单方法基于以下两个原因:     1.内

linux内核分析之进程地址空间【转】

转自:http://blog.csdn.net/bullbat/article/details/7106094 版权声明:本文为博主原创文章,未经博主允许不得转载. 本文主要介绍linux内核中进程地址空间的数据结构描述,包括mm_struct/vm_area_struct.进程线性地址区间的分配流程,并对相应的源代码做了注释.  内核中的函数以相当直接了当的方式获得动态内存.当给用户态进程分配内存时,情况完全不同了.进程对动态内存的请求被认为是不紧迫的,一般来说,内核总是尽量推迟给用户态进程分

简单理解linux内核的链表教程

在看linux内核源代码的时候,经常在一些结构里看见struct list_head结构.找了一下源代码,在list.h中,有对这个结构的定义,这个就是linux内核中的链表结构. 仔细看看这个结构,就可以发现它和以前在讲数据结构的时候的链表有很大的差别--没有数据.list_head结构中仅仅包含了两个自己结构的指针,用来组建双向循环链表.最大的疑问就是,这个链表结构如何保存数据呢? 在list.h中,定义了list_entry宏.这个宏就是用来提取包含链表项的结构的指针.从list_entr

Linux内核剖析 之 进程地址空间(二)

//接前一章,本节主要介绍线性区以及相关线性区的操作. 线性区 Linux通过类型为vm_area_struct的对象实现线性区. vm_area_struct: struct vm_area_struct { struct mm_struct * vm_mm; /* The address space we belong to. */ unsigned long vm_start; /* Our start address within vm_mm. */ unsigned long vm_e

Linux内核调试技术——进程D状态死锁检测

Linux的进程存在多种状态,如TASK_RUNNING的运行态.EXIT_DEAD的停止态和TASK_INTERRUPTIBLE的接收信号的等待状态等等(可在include/linux/sched.h中查看).其中有一种状态等待为TASK_UNINTERRUPTIBLE,称为D状态,该种状态下进程不接收信号,只能通过wake_up唤醒.处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,有时候进程在等待某种IO资源就绪时(wait_event机制)会设置进程进入该状态.一般情况

Linux内核剖析 之 进程地址空间(三)

本节主要讲述缺页异常处理程序和堆的管理等内容. 缺页异常处理程序 触发缺页异常程序的两种情况: 1. 由编程错误引起的异常(如访问越界,地址不属于进程地址空间). 2. 地址属于线性地址空间,但内核还未分配相应的物理页,导致缺页异常. 缺页异常处理程序总体方案: 线性区描述符可以让缺页异常处理程序非常有效的完成它的工作. do_page_fault()函数是80x86上的缺页中断服务程序,它把引起缺页的线性地址和当前进程的线性区相比较,从而根据具体方案选择适当的方法处理此异常. 标识符vmall