进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元。进程的生命周期: 创建:每个进程可以由父进程创建,进程可以创建子进程,子进程可以创建孙进程。 运行:多个进程可以同时存在,进程间可以通信。
撤销:进程可以撤销,从而结束一个进程的运行。
进程的三种状态: 就绪状态(ready):进程具备一切条件,正在等到分配处理器时间片;
执行状态(running):进程正在占用cpu;
阻塞状态(blocked):进程不能使用cpu,若等待时间发生,则将其唤醒。
Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。
进程的地址空间:数据段、代码段、堆栈段。数据段:存放的是全局变量、常数以及动态数据分配的数据空间;代码段:存放的是程序代码的数据;堆栈段:存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。进程ID是每个进程的唯一标示!进程ID:PID; 获取进程ID:getpid() ;父进程ID:PID; 获取父进程ID:getppid();用户ID:UID。创建进程方法1——fork()函数fork有3个返回值: 返回-1 表示创建失败;
返回0 表示子进程;
返回其他 表示父进程;
int main()
{
pid_t pid;
/*此时仅有一个进程*/
pid=fork();
/*此时已经有两个进程在同时运行*/
if(pid<0)
printf("error in fork!");
else if(pid==0)
printf("I am the child process, ID is %d
",getpid());//子进程
else
printf("I am the parent process,ID is %d
",getpid());//父进程
}
子父进程间存在写时拷贝,而不是资源共享。举个实例:int main(void)
{
pid_t pid;
int count=0;
pid = fork();
if (0 == pid)
{
count++;
printf( “count = %d
", count );
}
else if (pid > 0)
{
count++;
printf( “count = %d
", count );
}
return 0;
}
这段代码的执行结果是:count = 1;count = 1;第二次的输出并不是2。因为在父子进程在调用count时,分别拷贝了一份count原来的值,而不是后执行的进程使用先执行进程输出的值。创建进程方法2——vfork()函数创建的过程及返回值与fork函数一致,但与之区别的是,由vfork创建的父子进程之间是共享数据的。沿用上个实例,讲将fork换成vfork,输出结果就变成了:count = 1;//子进程输出的结果 count = 2;//父进程输出的结果而且,fork执行时父子进程的先后顺序是随机的,vfork执行父子进程是子先父后。为避免fork的父进程在子进程结束前先结束,导致子进程成为孤儿进程,出现一些异常的效果,可以在父进程的后面加一个wait函数:wait(&status)。它的作用是阻塞该进程,直到他的子进程结束,并且回收子进程的资源。退出进程exit()用来正常终结目前进程的执行,并把参数status返回给父进程,而进程所有的缓冲区数据会自动写回并关闭未关闭的文件。
_exit()用来立刻结束目前进程的执行,并把参数status返回给父进程,并关闭未关闭的文件。此函数调用后不会返回,并且会传递SIGCHLD信号给父进程,父进程可以由wait函数取得子进程结束状态。