程序是静态的,进程是正在执行的程序的一个实例,一个程序可以由多个进程组成.进程是资源分配的实体.
在进程被创建出来之后,该子进程几乎和父进程一样.子进程复制了父进程的地址空间,从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
并请联系谭海燕本人或者前往谭海燕个人主页留言