一、 进程的定义
程序的一次执行过程,同时也是资源分配的最小单元,它与程序有着本质的区别,程序是静态的,它是一些保存在磁盘上的指令有序集,没有任何的执行概念,而进程是动态的概念,它是程序执行的过程,包括了动态创建,调度和消亡的整个过程,对系统而言,当用户执行一个程序的时候,将启动一个进程。
二、进程是程序的执行过程,根据它的生命周期可以划分成3种状态。
· 执行态:该进程正在运行,即进程正在占用CPU。
· 就绪态:进程已经具备执行的一切条件,正在等待分配CPU的处理时间片。
· 等待态:进程不能使用CPU,若等待事件发生(等待的资源分配到)则可将其唤醒。
Linux中的进程包含3个段,分别为“数据段”、“代码段”和“堆栈段”。
· “数据段”存放的是全局变量、常数以及动态数据分配的数据空间,根据存放的数据,数据段又可以分成普通数据段(包括可读可写/只读数据段,存放静态初始化的全局变量或常量)、BSS数据段(存放未初始化的全局变量)以及堆(存放动态分配的数据)。
· “代码段”存放的是程序代码的数据。
· “堆栈段”存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。
由fork创建的新进程称为子进程,fork函数被调用一次,但返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程则是新子进程的进程ID。
父子进程共享fork后的代码段,子进程获得父进程的数据空间,堆,栈的拷贝,但是父子进程不共享这些存储空间部分。
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<math.h>
#include<string.h>
int glob=6; /*外部变量在初始化数据段*/
char buf[]="a write to stdout\n";
int main()
{
int var; /*自动变量存储在栈中*/
pid_t pid;
var=88;
if(write(STDOUT_FILENO,buf,sizeof(buf)-1) != sizeof(buf)-1)
printf("write error");
printf("before fork\n");
if((pid=fork())<0)
{
printf("fork error");
exit(0);
}
else if(pid==0) //child
{
glob++;
var++;
printf("buf is %s",buf);
}
else //parent
sleep(2);
printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);
exit(0);
}