通过Linux启动过程可以得知,所有进程都是init进程直接或者间接的fork出来的.
首先咱们来看看怎么创建子进程:
头文件 #include <unistd.h>
int fork(void); //创建一个子进程(开辟和父进程相同空间)
返回值:-1失败,成功返回创建的子进程的Id
int vfork(void); //创建一个子进程(共享父进程资源空间)
返回值:-1失败,成功返回创建的子进程的Id
- int pid = fork();
- int c = 0;
- if(pid == 0){ //返回值在子进程中为0;所以当等于0时就是在子进程中运行
- c++;
- printf("children,c=%d\n",c);
- }else if(pid > 0){ //返回值在父进程中就是子进程的PID号,所以大于0就是在父进程中执行
- c++;
- printf("father,c=%d\n",c);
- }else { //小于0,子进程创建失败
- printf("子进程创建失败\n");
- }
结果为:children,c=1
father,c=1
因为是拷贝父进程的资源,所以变量c也被拷贝了一份到子进程,所以在父子进程中对变量c进行操作不会相互影响,而且父子进程谁先执行谁后执行由系统进程调度决定,而使用vfork()函数则会共享,而且需要注意的是vfork函数产生的子进程会被优先调度,父进程会等子进程运行结束以后才会被调用,而且子进程结束以后必须调用exit函数返回,否则进程异常退出.
- int c = 0;
- int pid = vfork();
- if(pid == 0){
- c++;
- printf("c c=%d\n",c);
- exit(0); //调用该函数返回
- }
- if(pid > 0){
- c++;
- printf("f c=%d\n",c);
- }
- if(pid < 0){
- printf("子进程创建失败\n");
- }
运行结果为:c c=2;
f c=3;
vfork函数使得父进程等待子进程完成工作后调用可以防止子进程成为僵尸进程,而且节约内存空间,所以在满足需求的情况下可以尽量选择vfork函数创建子进程.
------------------------------------------------------------------------------------------------
一些其他的相关函数:
头文件<sys/types.h>,<unsid.h>
int getpid(void);//得到进程Id
int getppid(void);//得到父进程Id
头文件<sys/types.h><sys/wait.h>
int wait(int *status);//暂停目前进程的执行,直到有信号来激活或者子进程执行结束
int waitpid(int pid,int *status,int options);
//等待pid代表的子进程的执行结束,pid = -1,相当于wait。等待任何子进程
头文件<unsid.h>
unsigned int sleep(unsigned int seconds)//当前进程休眠
头文件<unsid.h>
void exit(int status);//结束进程,更新缓存区
oid _exit(int status);//结束进程,清空缓存区