转载:http://blog.sina.com.cn/s/blog_69708ebe0100rc3i.html
1.什么是进程
1,通俗来讲,进程是系统中正在运行的一个程序,程序一旦运行就是进程。但要把进程和程序区分开来,程序代码储存在内存空间,它是静态的,它是保存在磁盘上的指令的有序集合,没有任何执行的概念,而进程是动态的,它的生命周期有三种状态:就绪态,执行态,等待态。一个进程执行后可以被消亡,但是程序依然存在,只是此时这个程序不执行而已;
2,进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。
3,一个程序运行起来可产生一个或多个进程,一个进程也可以包含多个程序,他们不是一一对应关系;
4,进程是系统的基本调度单位,那么怎样区分不同的进程呢?每个进程都有自己的身份证(进程标识),其中最重要的标识是进程号(PID)和它的父进程号(PPID),他们都是非零的正整数,可分别通过getpid()和getppid()得到进程号和父进程号;
linux中的进程包含三个段:
数据段:存放全局变量,常数以及动态数据分配的数据空间(如malloc函数取得的空间)等;
代码段:当然是存代码!!!
堆栈断:存子程序的返回地址,子程序的参数和局部变量;
2.进程的相关函数
linux中,进程的执行分用户模式和内核模式;用户进程可在两种模式下运行;
创建进程:
fork();在一个进程中创建一个新进程(子进程),该子进程完全拷贝了父进程的全部内容(复制父进程数据和堆栈空间等);
vfork()和fork()有一个区别: Linux使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。
exec函数族:提供了一个在进程中启动另一个执行程序的方法;exec函数族共有6个函数,具体用法请查看linux_c函数参考手册,下面是几个例子供参考:
#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”有关,自己去想吧!!
_exit()直接结束进程。
wait()和waitpid()
怎样用自己去看书,我直接给出例子,不要怪我哦,我打字打到这里是在太累了,哈:
#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 "); sleep(1); } }while(pr==0); if(pr==pc) printf("Get child %d",pr); else printf("somer error occured"); } }