fork后,先运行父进程,再运行子进程

本文介绍如何使用fork()函数创建新进程,并通过getpid()和getppid()函数获取当前进程及其父进程的ID。通过示例代码展示了进程创建及PID获取的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建一个新的进程pid_t fork(void)
返回值:失败 -1
成功,两次返回
父进程返回子进程的id
子进程返回0

pid_t getpid(void)
获得pid,进程id,获得当前进程pid_t getpid(void);

pid_t getppid(void)
获得当前进程父进程的id pid_t getppid(void);

#include <sys/types.h>
#include <unistd.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc ,char argv[])
{
	printf("Begin ....\n");

	pid_t pid=fork();
	if(pid<0)
	{perror("fork err");
		exit(1);
	}
	if(pid==0)
	{
		printf("I am a child, pid=%d,ppid=%d\n",getpid(),getppid());
	}
	else if(pid>0)
	{
		printf("childpid=%d,self=%d,ppid=%d\n",pid,getpid(),getppid());
	}

### Fork 创建的父进程子进程的关系 Fork 调用用于创建新进程,该操作由现有进程发起并复制其当前状态来形成新的子进程。在 fork 执行之后,两个几乎完全相同的进程中有一个是原进程(父进程),另一个是由前者派生出来的副本(子进程)。父子两者的区别在于返回值以及它们各自的 PID 和 PPID (父进程 ID)[^1]。 对于父进程而言,在成功调用 `fork()` 后会获得一个正值作为子进程的 PID;而子进程则会在相同位置收到 0 的返回结果,并且拥有自己独立的新 PID 。这种机制允许程序区分哪个部分正在父进程中执行,哪些是在新生的子进程运行[^3]。 #### 关键属性对比 | 属性 | 父进程 | 子进程 | | --- | ------ | -------| | 返回值 | 新建子进程的 PID | 总为 0 | | 自身 PID | 不变 | 新分配 | | 父进程 PID | 不变 | 继承自父进程 | ### 行为差异 - **资源共享**:尽管两者看起来相似,但实际上除了某些特定的数据结构外,比如文件描述符表项等会被二者共同持有之外,其他大部分内存映像都会被操作系统标记为写时拷贝(Copy-On-Write),这意味着只有当任意一方尝试修改数据时才会真正分离出单独的一份副本给改方使用[^2]。 - **终止通知**:一旦子进程结束生命周期,不会立即释放其所占用的所有系统资源直到对应的僵尸(zombie)条目被清理掉为止——这通常发生在父进程通过 wait 或 waitpid 类型的功能收集到有关已故子女的信息之时。如果子进程异常退出,则可以通过宏 WIFSIGNALED 来检测相应的信号编号[^4]。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid; printf("Before forking.\n"); pid = fork(); if (pid < 0){ fprintf(stderr,"Fork failed\n"); exit(1); }else if(pid == 0){ // Child process printf("This is child process, my PID=%d and parent's PID=%d\n",getpid(), getppid()); sleep(5); // Simulate work _exit(EXIT_SUCCESS); // Exit without calling cleanup handlers. } else{ // Parent process int status; wait(&status); // Wait until the child has finished. if(WIFEXITED(status)){ printf("Child exited normally with code %d\n", WEXITSTATUS(status)); } if(WIFSIGNALED(status)){ printf("Child terminated by signal %d\n", WTERMSIG(status)); } printf("Parent got message from child. My PID=%d\n", getpid()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值