进程(二)
来源:互联网 发布:mysql use index用法 编辑:程序博客网 时间:2024/06/04 18:54
1.fork()
fork创建一个新进程。这个系统调用复制当前进程,在进程表中创建一个新的表项,新进程几乎与原进程一模一样,执行的代码也是完全一样,但新进程有自己的数据空间、环境、文件描述符。
#include<sys/types.h>#include<unistd.h>pid_t fork(void);返回值:
- 如果成功创建一个子进程,对于父进程来说返回子进程ID
- 如果成功创建一个子进程,对于子进程来说返回值为0
- 如果为-1表示创建失败
- 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
- 子进程与父进程的区别在于:
- 1、父进程设置的锁,子进程不继承
- 2、各自的进程ID和父进程ID不同
- 3、子进程的未决告警被清除;
- 4、子进程的未决信号集设置为空集。
3. fork系统调用需要注意的地方
- fork系统调用之后,父子进程将交替执行。
- 如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)
- 如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程。
- 子进程退出会发送SIGCHLD信号给父进程,可以选择忽略或使用信号处理函数接收处理就可以避免僵尸进程。
一个fork的例子/*fork.c*/#include<stdio.h>#include<unistd.h>#include<sys/types.h>int main(){ pid_t pid; char *message; pid=fork(); if(pid<0) {perror("fork error!");exit(1); } else if(pid>0) {message="this is parent!";printf("%s ppid=%d\n",message,pid); } else {message="this is child!";printf("%s ppid=%d\n",message,pid); } return 0;}make fork./fork1结果是:this is parent! ppid=2486zhou@hyn-virtual-machine:~/os/test/test1/daemon$ this is child! ppid=0结果是乱的,别急我们来看第二个函数;
2.wait()
在例程fork1.c中由于父进程先于子进程结束;所以输出结果有点乱,我们可以在父进程中调用wait()等待子进程结束;
#include<sys/types.h>#include<sys/wait.h>pid_t wait(int *stat_loc);wait()会暂时停止进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一起返回。如果不在意结束状态值,则参数status 可以设成NULL。
结束状态值信息:
- WIFEXITED(stat_val)如果子进程正常结束,他就取一个非零值
- WEXITSTATUS(stat_val)如果WIFEXITED非零,他返回子进程的退出码
- WIFSIGNALED(stat_val)如果子进程因为一个未捕获的信号而终止,他就取一个非零值
- WTERMSIG(stat_val)如果WIFSIGNALED非零,他返回一个信号代码
- WIFSTOPPED(stat_val)如果子进程意外终止,它就取一个非零值
- WSTOPSIG(stat_val)如果WIFSTOPPED非零,他返回一个信号代码
一个wait的例子
/*wait.c*/#include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>int main(){ pid_t pid; char *message; pid=fork(); int exit_code; if(pid<0) {perror("fork error!");exit(1); } else if(pid>0) {message="this is parent!";printf("%s ppid=%d\n",message,pid);int stat_val;pid_t child_pid;child_pid=wait(&stat_val);if(WIFEXITED(stat_val)){printf("child exited with code%d\n",WEXITSTATUS(stat_val));}else{printf("child terminated abnormally\n");} } else {message="this is child!";printf("%s ppid=%d\n",message,pid);exit_code=37; } exit(exit_code);}make wait./wait结果是this is parent! ppid=2576this is child! ppid=0child exited with code37
- 进程管理(二)进程
- 进程管理(二)
- 进程(二)
- 进程保护(二)
- 进程管理(二)
- 进程调度(二)
- 进程管理(二)
- Linux进程(二)
- Python_进程(二)
- [linux]进程(二)--进程地址空间
- Nginx进程模型(二)worker进程
- 进程控制(二)进程控制编程
- C++进程检测,发现进程路径,关闭进程(二)
- 进程(二)——进程标识符&&进程位置
- 进程间通信(二)
- 进程之基础知识(二)
- 进程之基础知识(二)
- 创建进程-CreateProcess (二)
- nginx+keepalived高可用性负载均衡
- 进程
- 呃呃呃
- awk+sed+sort常用命令收集
- NGINX 的301 重定向
- 进程(二)
- LINUX/UNIX下的回车换行与WINDOWS下的区别
- RCP动态菜单添加
- Linux下串口编程
- Linux下安装MySQL
- Java高级进阶学习-Java的内存回收(3)
- ubuntu常用命令收集
- PL/SQL Developer 9.x 注册码
- UVa 458 The Decoder (最简代码!)