网站开发人员的行业分析企业咨询端app
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:36
当前位置: 首页 > news >正文
网站开发人员的行业分析,企业咨询端app,广东建设部官方网站,求几个能用的地址2021引言 在Linux系统中#xff0c;进程管理是核心功能之一。理解进程的创建、执行和终止是系统编程中的基础。本文将深入探讨Linux中的进程控制机制#xff0c;包括进程的生命周期、父子进程的交互、以及进程状态的管理
- 进程创建#xff1a;fork()函数 在Linux操作系统中…引言 在Linux系统中进程管理是核心功能之一。理解进程的创建、执行和终止是系统编程中的基础。本文将深入探讨Linux中的进程控制机制包括进程的生命周期、父子进程的交互、以及进程状态的管理
- 进程创建fork()函数 在Linux操作系统中fork()是用于创建新进程的主要系统调用。通过此函数当前进程父进程创建一个新的进程子进程子进程是父进程的一个复制品。 关键点 父进程和子进程的关系父进程通过fork()返回子进程的PID进行标识和管理而子进程中fork()返回0以区分两者的执行流。内存和资源的复制fork()实际上在内存层面采用了写时拷贝技术优化了资源的使用。代码示例 #include unistd.h #include stdio.hint main() {pid_t pid fork();if (pid 0) {printf(This is the child process.\n);} else {printf(This is the parent process. Child PID: %d\n, pid);}return 0; }当一个进程调用fork之后就有两个二进制代码相同的进程。那么我们知道 fork函数父进程返回的是子进程的Pid,子进程返回0的原因是方便父进程对子进程进行标识从而进行分流。 当进程结束后我们就要谈到今天的重点话题进程终止 首先我们说当一个进程结束之后就要终止了 进程退出场景有哪些呢 代码运行完毕结果正确 代码运行完毕结果不正确 代码异常终止 首先终止是在做什么 先释放曾经的代码和数据占据的空间然后释放内核数据结构task_struct会被延期处理会处于Z僵尸状态 2.进程终止的3种情况 代码跑完结果正确。代码跑完结果不正确。可以通过进程的退出码决定代码执行时出现了异常导致提前退出。一旦出现异常退出码就没有意义了。那么为什么出现异常本质是因为进程收到了OS发给进程的信号 3.所以我们衡量一个进程退出只需要两个数字退出码和退出信号 那么我们如何终止进程呢 进程常见退出方法 正常终止可以通过 echo \(? 查看进程退出码 1. 从 main 返回 2. 调用 exit 3._exit 异常退出 ctrl c 信号终止 首先可以main直接return表示进程终止非main函数return叫做函数结束其次代码调用exit函数也可以终止进程。在代码的任意位置调用都表示进程退出。最后我们还可以采用_exit,这是一个system call.区别是什么呢Exit会在退出的时候刷新缓冲区_exit不会。目前我们所说的缓冲区不是内核缓冲区一定不在操作系统内部因为exit本质是调用_exit。 _exit函数 #include unistd.h void _exit(int status); 参数status 定义了进程的终止状态父进程通过wait来获取该值 说明虽然status是int但是仅有低8位可以被父进程所用。所以_exit(-1)时在终端执行\)?发现返回值 是255。 exit函数 #include unistd.h void exit(int status); exit 最后也会调用 exit, 但在调用 exit 之前还做了其他工作 1. 执行用户通过 atexit 或 on_exit 定义的清理函数。 2. 关闭所有打开的流所有的缓存数据均被写入 3. 调用 _exit 进程等待 之前讲过子进程退出父进程如果不管不顾就可能造成‘僵尸进程’的问题进而造成内存泄漏。 另外进程一旦变成僵尸状态那就刀枪不入“杀人不眨眼”的kill -9 也无能为力因为谁也没有办法 杀死一个已经死去的进程。 最后父进程派给子进程的任务完成的如何我们需要知道。如子进程运行完成结果对还是不对 或者是否正常退出。 父进程通过进程等待的方式回收子进程资源 为防止僵尸进程的出现父进程需要等待子进程结束这可以通过wait()或waitpid()函数实现。 wait()阻塞当前进程直到一个子进程结束。waitpid()提供更多控制如非阻塞等待允许父进程在子进程运行时执行其他任务。 wait方法 #includesys/types.h #includesys/wait.h pidt wait(int*status); 返回值成功返回被等待进程pid失败返回-1。 参数输出型参数 waitpid 方法 pid t waitpid(pid_t pid, int *status, int options); 返回值当正常返回的时候waitpid返回收集到的子进程的进程ID如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在 参数pidPid-1,等待任一个子进程。与wait等效。Pid0.等待其进程ID与pid相等的子进程。status:WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码options:WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进 程的ID。 获取子进程 status wait 和 waitpid 都有一个 status 参数该参数是一个输出型参数由操作系统填充。 如果传递 NULL 表示不关心子进程的退出状态信息。 否则操作系统会根据该参数将子进程的退出信息反馈给父进程。 status 不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究 status 低 16 比特位 测试代码 #include sys/wait.h #include stdio.h #include stdlib.h #include string.h #include errno.h int main( void ){pid_t pid;if ( (pidfork()) -1 )perror(fork),exit(1);if ( pid 0 ){sleep(20);exit(10);} else {int st;int ret wait(st);if ( ret 0 ( st 0X7F ) 0 ){ // 正常退出printf(child exit code:%d\n, (st8)0XFF);} else if( ret 0 ) { // 异常退出printf(sig code : %d\n, st0X7F );}} }测试结果[rootlocalhost linux]# ./a.out #等20秒退出child exit code:10 [rootlocalhost linux]# ./a.out #在其他终端kill掉sig code : 9 具体代码实现 非阻塞等待等待成功子进程退出了父进程回收成pid_t 0,反之pid0.pid_t0:检测是成功的只不过子进程没退出需要你下一次重复等待。所以我们一般都是 通过 非阻塞等待的时候循环来确定状态这个就叫非阻塞轮询。在非阻塞轮询的过程中允许父进程做一些其他的事 进程的阻塞等待方式: int main() {pid_t pid;pid fork();if(pid 0){printf(%s fork error\n,FUNCTION);return 1;} else if( pid 0 ){ //childprintf(child is run, pid is : %d\n,getpid());sleep(5);exit(257);} else{int status 0;pid_t ret waitpid(-1, status, 0);//阻塞式等待等待5Sprintf(this is test for wait\n);if( WIFEXITED(status) ret pid ){printf(wait child 5s success, child return code is :%d.\n,WEXITSTATUS(status));}else{printf(wait child failed, return.\n);return 1;} }return 0; } 运行结果: [rootlocalhost linux]# ./a.out child is run, pid is : 45110 this is test for wait wait child 5s success, child return code is :1. 进程的非阻塞等待方式 #include stdio.h #include unistd.h #include stdlib.h #include sys/wait.h int main() {pid_t pid;pid fork();if(pid 0){printf(%s fork error\n,FUNCTION);return 1;}else if( pid 0 ){ //childprintf(child is run, pid is : %d\n,getpid());sleep(5);exit(1);} else{int status 0;pid_t ret 0;do{ret waitpid(-1, status, WNOHANG);//非阻塞式等待if( ret 0 ){printf(child is running\n);}sleep(1);}while(ret 0);if( WIFEXITED(status) ret pid ){printf(wait child 5s success, child return code is :%d.\n,WEXITSTATUS(status));}else{printf(wait child failed, return.\n);return 1;}}return 0; } 进程程序替换 用 fork 创建子进程后执行的是和父进程相同的程序 ( 但有可能执行不同的代码分支 ), 子进程往往要调用一种 exec 函数以执行另一个程序。当进程调用一种exec 函数时 , 该进程的用户空间代码和数据完全被新程序替换 , 从新程序的启动例程开始执行。调用exec 并不创建新进程 , 所以调用 exec 前后该进程的 id 并未改变 替换函数 其实有六种以 exec 开头的函数 , 统称 exec 函数 #include unistd.h int execl(const char *path, const char *arg, …); int execlp(const char *file, const char *arg, …); int execle(const char *path, const char *arg, …,char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); 函数解释 这些函数如果调用成功则加载新的程序从启动代码开始执行 , 不再返回。 如果调用出错则返回 -1 所以 exec 函数只有出错的返回值而没有成功的返回值。 命名理解 这些函数原型看起来很容易混 , 但只要掌握了规律就很好记 l(list) : 表示参数采用列表 v(vector) : 参数用数组 p(path) : 有p自动搜索环境变量PATH e(env) : 表示自己维护环境变量 exec 调用举例如下 : #include unistd.h int main() {char *const argv[] {ps, -ef, NULL};char *const envp[] {PATH/bin:/usr/bin, TERMconsole, NULL};execl(/bin/ps, ps, -ef, NULL);// 带p的可以使用环境变量PATH无需写全路径execlp(ps, ps, -ef, NULL);// 带e的需要自己组装环境变量execle(ps, ps, -ef, NULL, envp);execv(/bin/ps, argv);// 带p的可以使用环境变量PATH无需写全路径execvp(ps, argv);// 带e的需要自己组装环境变量execve(/bin/ps, argv, envp);exit(0); } 理解Linux中的进程管理是高效系统编程的关键。通过掌握fork(), exit(), wait()和exec()等系统调用开发者可以有效地控制进程的生命周期和行为。这些概念的深入了解和实际应用对于任何系统程序员来说都是必不可少的技能。
- 上一篇: 网站开发人员的行业分析电脑版网站制作公司
- 下一篇: 网站开发人员调试百度seo优化是做什么的
相关文章
-
网站开发人员的行业分析电脑版网站制作公司
网站开发人员的行业分析电脑版网站制作公司
- 技术栈
- 2026年03月21日
-
网站开发人力成本做网站都需要会什么软件
网站开发人力成本做网站都需要会什么软件
- 技术栈
- 2026年03月21日
-
网站开发去哪里培训免费全能浏览器
网站开发去哪里培训免费全能浏览器
- 技术栈
- 2026年03月21日
-
网站开发人员调试百度seo优化是做什么的
网站开发人员调试百度seo优化是做什么的
- 技术栈
- 2026年03月21日
-
网站开发人员兼职购物网站如何建设
网站开发人员兼职购物网站如何建设
- 技术栈
- 2026年03月21日
-
网站开发人员叫什么seo优化专员
网站开发人员叫什么seo优化专员
- 技术栈
- 2026年03月21日






