fork()函数创建进程举例

本文介绍了Linux系统中的fork()函数,用于创建进程。通过实例解析fork()的特点和使用,包括如何判断进程身份,以及不同情况下的输出结果和进程关系。详细探讨了多个fork()调用示例,帮助读者深入理解进程创建过程。

fork()是什么?
fork()是Linux系统中的分叉函数,我们可以把它想象成一个倒立的叉子。它通过系统调用创建一个与原来进程几乎完全相同的进程。一个进程调用fork()后,创建一个子进程,它拥有父进程完全一样的代码和数据,相当于父进程的一个克隆。
在这里插入图片描述

fork()的特点
子进程与父进程相互独立。
一次调用,两次返回。
若返回值为0,则为子进程;若返回值不为0,则它是父进程。负值则表示出错。
fork()函数示例

/*
 * forks.c - Examples of Unix process control
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> 
#include <signal.h>

/*
 * fork0 - The simplest fork example
 * Call once, return twice
 * Creates child that is identical to parent
 * Returns 0 to child process
 * Returns child PID to parent process
 */
void fork0() 
{
    if (fork() == 0) {
	printf("Hello from child\n");
    }
    else {
	printf("Hello from parent\n");
    }
}

/* 
 * fork1 - Simple fork example 
 * Parent and child 
### `fork()` 函数的作用详解(附示例) `fork()` 是 Unix/Linux 系统编程中最重要的系统调用之一,它的核心作用是**创建当前进程的副本**。以下是具体说明和示例: --- #### **作用本质** 1. **克隆当前进程**:创建一个与父进程几乎完全相同的子进程 2. **执行流分叉**:调用后父子进程并发执行(父进程继续执行,子进程fork()返回处开始执行) 3. **区别仅在于**: - 进程ID不同 - 返回值不同(父进程返回子进程PID,子进程返回0) --- #### **代码示例** ```c #include <stdio.h> #include <unistd.h> int main() { printf("准备fork(进程ID:%d)\n", getpid()); pid_t child_pid = fork(); // 分叉点 // 从这里开始有两个执行流 if (child_pid == 0) { // 子进程执行区 printf("子进程: PID=%d, 父PID=%d\n", getpid(), getppid()); } else if (child_pid > 0) { // 父进程执行区 printf("父进程: 我的PID=%d, 子进程PID=%d\n", getpid(), child_pid); } else { perror("fork失败"); return 1; } printf("本消息会打印两次(来自PID:%d)\n\n", getpid()); return 0; } ``` --- #### **典型输出结果** ``` 准备fork(进程ID:1234) 父进程: 我的PID=1234, 子进程PID=1235 本消息会打印两次(来自PID:1234) 子进程: PID=1235, 父PID=1234 本消息会打印两次(来自PID:1235) ``` --- #### **关键特性说明** | 特性 | 说明 | |------|------| | **写时复制** | 父子进程共享内存空间,只有修改时才会复制(高效) | | **独立地址空间** | 修改变量互不影响(示例见下方) | | **执行顺序不确定** | 由系统调度决定父子进程谁先运行 | --- #### **变量隔离示例** ```c int shared = 1; pid_t pid = fork(); if (pid == 0) { shared = 100; // 子进程修改 printf("Child sees: %d\n", shared); // 输出100 } else { sleep(1); // 确保子进程先执行 printf("Parent sees: %d\n", shared); // 仍输出1 } ``` --- #### **常见应用场景** 1. **Shell实现**:每个命令在新进程中执行 2. **服务器并发**:为每个连接创建进程处理 3. **并行计算**:分治任务处理(需配合IPC) 4. **进程监控**:通过子进程执行危险操作 --- #### **注意事项** 1. 避免"fork炸弹"(无限递归fork) 2. 子进程需要正确退出(避免僵尸进程) 3. 文件描述符会被复制(可能导致意外共享)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值