转载:http://blog.sina.com.cn/s/blog_69708ebe0100rc3i.htmlhtml
1,通俗来说,进程是系统中正在运行的一个程序,程序一旦运行就是进程。但要把进程和程序区分开来,程序代码储存在内存空间,它是静态的,它是保存在磁盘上的指令的有序集合,没有任何执行的概念,而进程是动态的,它的生命周期有三种状态:就绪态,执行态,等待态。一个进程执行后能够被消亡,可是程序依然存在,只是此时这个程序不执行而已;linux
2,进程能够当作程序执行的一个实例。进程是系统资源分配的独立实体,每一个进程都拥有独立的地址空间。一个进程没法访问另外一个进程的变量和数据结构,若是想让一个进程访问另外一个进程的资源,须要使用进程间通讯,好比管道,文件,套接字等。数据结构
3,一个程序运行起来可产生一个或多个进程,一个进程也能够包含多个程序,他们不是一一对应关系;
4,进程是系统的基本调度单位,那么怎样区分不一样的进程呢?每一个进程都有本身的身份证(进程标识),其中最重要的标识是进程号(PID)和它的父进程号(PPID),他们都是非零的正整数,可分别经过getpid()和getppid()获得进程号和父进程号;函数
linux中的进程包含三个段:
数据段:存放全局变量,常数以及动态数据分配的数据空间(如malloc函数取得的空间)等;
代码段:固然是存代码!!!
堆栈断:存子程序的返回地址,子程序的参数和局部变量;spa
linux中,进程的执行分用户模式和内核模式;用户进程可在两种模式下运行;
建立进程:
fork();在一个进程中建立一个新进程(子进程),该子进程彻底拷贝了父进程的所有内容(复制父进程数据和堆栈空间等);
vfork()和fork()有一个区别: Linux使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会作真正的复制动做,因为这些继承的信息是复制而来,并不是指相同的内存空间,所以子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。
exec函数族:提供了一个在进程中启动另外一个执行程序的方法;exec函数族共有6个函数,具体用法请查看linux_c函数参考手册,下面是几个例子供参考:code
#include<unistd.h> #include<stdio.h> #include<stdlib.h> int main() { if(fork()==0) //若返回值为0,是子进程 { if(execl("/bin/rm","rm","hello",NULL)<0) perror("execlp error "); } return 0; }
#include<unistd.h> #include<stdio.h> #include<stdlib.h> int main() { if(fork()==0) //子进程 { if(execlp("touch","touch","hello",NULL)<0) perror("execlp error "); } return 0; }
exit()和_exit();这两个函数都是用来终止进程的,区别就在exit()在终止进程前要检查文件打开的状况,会把缓冲区的数据写回文件,这个操做跟“缓冲IO”有关,本身去想吧!!htm
_exit()直接结束进程。
wait()和waitpid()
怎样用本身去看书,我直接给出例子,不要怪我哦,我打字打到这里是在太累了,哈:blog
#include<sys/types.h> #include<sys/wait.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h> int main() { pid_t pc,pr; pc=fork();//产生一个子进程 if(pc<0)//出错 perror("fork"); else if(pc==0) //返回值为0,是子进程 { sleep(5); exit(0); } else //为父进程 { do { pr=waitpid(pc,NULL,WNOHANG); if(pr==0) { printf("the child process has not exit\n"); sleep(1); } }while(pr==0); if(pr==pc) printf("Get child %d",pr); else printf("somer error occured"); } }