进制控制原语
来源:互联网 发布:2017年淘宝好做吗 编辑:程序博客网 时间:2024/05/20 05:03
fork函数
由fork创建的新进程被称为子进程(child process),fork函数被调用一次,但返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。将子进程ID返回给父进程的理由是:因为一个进程的子进程可以有多个,并且没有一个函数使一个进程可以获得其所有子进程的进程ID。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID(进程ID 0 总是由内核交换进程使用,所以一个子进程的进程ID不可能为 0)。子进程是父进程的副本。
//fork - create a child process,返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1#include <unistd.h>pid_t fork(void);
父、子进程之间的区别是:
- 列表内容
- fork的返回值
- 进程ID不同
- 两个进程具有不同的父进程ID:子进程的父进程ID是创建它的进程的ID,而父进程的父进程ID则不变
- 子进程的tms_utime,tms_stime,tms_cutime以及tms_ustime均被设置为0
- 父进程设置的文件锁不会被子进程
- 子进程的未处理的闹钟( alarm )被清除
- 子进程的未处理信号集设置为空集
fork有两种用法:
- 一个父进程希望复制自己,使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的–父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一个服务请求到达。
- 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec
使用fork失败的主要原因是:
- 系统中已经有了太多的进程
- 该实际用户ID的进程总数超过了系统限制
/*****************************************> File Name : fork.cpp> Description : fork两次,避免僵死进程 gcc -g -o fork fork.cpp> Author : linden> Date : 2016-01-25*******************************************/#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/wait.h>#include <sys/types.h>int main(void){ pid_t pid; if ((pid = fork()) < 0) { fprintf(stderr, "Fork error!\n"); exit(-1); } else if (pid == 0) /* first child */ { if ((pid = fork()) < 0) { fprintf(stderr, "Fork error!\n"); exit(-1); } else if (pid > 0) exit(0); /* parent from second fork == first child */ /* * We're the second child; our parent becomes init as soon * as our real parent calls exit() in the statement above. * Here's where we'd continue executing, knowing that when * we're done, init will reap our status. */ sleep(2); printf("Second child, parent pid = %d\n", getppid()); exit(0); } if (waitpid(pid, NULL, 0) != pid) /* wait for first child */ { fprintf(stderr, "Waitpid error!\n"); exit(-1); } /* * We're the parent (the original process); we continue executing, * knowing that we're not the parent of the second child. */ exit(0);}
wait和waitpid函数
调用wait或waitpid的进程可能会发生的情况:
- 如果其所有子进程都还在运行,则阻塞
- 如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
- 如果它没有任何子进程,则立即出错返回
如果进程由于接收到SIGCHLD信号而调用wait,则可期望wait会立即返回。但是如果在任意时刻调用wait,则进程可能会阻塞。
//参数statloc是一个整型指针。如果statloc不是一个空指针,则终止进程的终止状态就存放在它所指向的单元内。如果不关心终止状态,则可将该参数指定为空指针。两者返回值:若成功返回进程ID,0,若出错返回-1#include <sys/wait.h>pid_t wait(int *statloc);pid_t waitpid(pid_t pid, int *statloc, int options);
两函数区别:
- 在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞
- waitpid并不等待在其调用之后的第一个终止子进程,它有若干个选项,可以控制它所等待的进程
/*****************************************> File Name : fork.cpp> Description : fork示例代码 gcc -g -o fork fork.cpp> Author : linden> Date : 2016-01-22*******************************************/#include <unistd.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>void pre_exit(int status){ if (WIFEXITED(status)) { printf("normal termination,exit status = %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("abnormal termination,signal number = %d%s\n", WTERMSIG(status),#ifdef WCOREDUMP WCOREDUMP(status) ? " (core fire generated) " : "");#else "");#endif } else if (WIFSTOPPED(status)) { printf("child stopped,signal number = %d\n",WSTOPSIG(status)); }}int main(int argc, char *argv[]){ pid_t pid; pid = fork(); if (0 > pid) { perror("fork error:"); } else if (0 == pid) { printf("This is the child process: %d, ppid = %d.\n", getpid(),getppid()); exit(0); } printf("This is the parent process: %d.\n", getpid()); //判断子进程结束:wait子进程结束 int status; if (wait(&status) != pid) { perror("Error --> wait:"); } pre_exit(status); return 0;}
0 0
- 进制控制原语
- 进程控制原语
- linux进程控制原语
- Linux进程控制fork原语
- linux线程控制原语1
- linux线程控制原语2
- Unix线程概念、控制原语、属性
- (原)控制反转
- 操作系统(六)--------进程控制操作(原语)
- 原语
- 原语
- 原语
- 原语??
- 原语
- 进(线)程同步原语
- 进制与反码补码原码
- 原语 原语操作 原子操作
- p原语和v原语
- 后台播放音频,不同Activity,统一控制,已封装,轻松集成
- Git 分支的理解
- (二)在Android硬件抽象层增加接口模块访问硬件驱动程序
- Codeforces Round #336 (Div. 2) D. Zuma(区间dp)
- 第11章 掌握GCD(唐巧《IOS开发进阶》)
- 进制控制原语
- pg中replace和translate的用法(数据少的中文排序)
- linux常用命令—— 网络通信(十)
- 关于ListView中adapter调用notifyDataSetChanged失效的原因总结
- WINDOWS API——OPENCLIPBOARD——剪切板
- java.lang.IncompatibleClassChangeError
- 把$date = '08/26/2003' 转换成2003/08/26
- asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
- 程序员常用Photoshop工具教程 (格式转换,裁剪)