Linux中使用fork创建子进程详解及示例代码 | 嵌入式Linux应用开发篇 - 02

1. 进程

1.1. 什么是进程

当可执行文件开始运行之后,就变为了系统中的一个进程,一个程序(可执行文件)运行起来之后可以创建多个进程执行,称之为多进程程序。

每个进程包含有进程运行环境、内存地址空间、进程ID、和至少一个被称为线程的执行控制流等资源。

系统中所有的这些进程实体共享计算机系统的 CPU、外设、内存等资源。

1.2. 进程的状态

系统中的一个CPU在某一个时刻只能执行一个进程,系统中存在的这些多个进程按照一定的规则轮流交替执行,所以每个进程会产生不同的状态:

  • R:运行态或者就绪态,一旦等待CPU,立马执行;
  • S:可中断的睡眠状态(因为等待某种事件的发生而被挂起);
  • D:不可中断的睡眠状态(此时不能响应异步信号);
  • T:暂停状态;
  • W:退出状态,进程即将被销毁;
  • Z:退出状态,进程成为僵尸进程;

2. 编写多进程程序——创建子进程

2.1. 头文件

在使用多进程编程的API时,必须首先包含以下头文件:

#include <unistd.h>		//定义了fork函数

2.2. 创建进程

函数原型如下:

pid_t fork(void);

fork函数用来创建子进程,它是通过复制父进程得到的子进程,所以:

  • 子进程将继承父进程的整个地址空间;
  • 子进程只有pid号和父进程不一样;

fork函数会复制出子进程,接着子进程和父进程都处于就绪状态,开始由内核调度执行,所以,被调用的fork函数会返回两次

  • 父进程返回一次,返回的 pid_t 类型的值为新创建的子进程的pid;
  • 子进程返回一次,返回的 pid_t 类型的值为0;

如果创建失败,父进程会返回-1。

另外,pid_t类型其实就是short类型。

2.3. 获取PID的函数

在头文件<unistd.h>中定义,原型如下:

  • 获取自己的pid
pid_t getpid(void);
  • 在子进程中获取父进程的pid
pid_t getppid(void);

2.4. 创建子进程的示例代码

/**
 * @brief  使用fork创建子进程示例程序
 * @author Mculover666
 * @note   创建一个子进程,打印父进程和子进程的pid,并测试n的值
*/

#include <unistd.h>
#include <stdio.h>

int main(void)
{
    pid_t pid;

    int n = 0;  //测试父进程和子进程是否共享一个n

    pid = fork();

    if(pid < 0)
    {
        /* 创建子进程失败 */
        printf("fork fail.\n");
        return -1;
    }
    else if(pid == 0)
    {
        /* 子进程执行的程序 */
        n += 1;
        printf("I am child, my pid = %d, my father pid = %d, n = %d.\n", getpid(), getppid(), n);
        return 0;
    }
    else
    {
        /* 父进程要执行的程序 */
        n += 2;
        printf("I am father, my pid = %d, my child pid = %d, n = %d.\n", getpid(), pid, n);
        return 0;
    }
}

编译:

gcc 02-fork_test.c -o 02-fork_test.o

执行:

由执行结果可以看到,n变量被子进程fork过去之后,在子进程中就有了一个新的变量n,所以父进程执行后n = 2,子进程执行后n = 1,不是同一个n。

2.5. 移植到嵌入式Linux开发板上运行测试

① 使用交叉编译工具重新编译程序:

arm-none-linux-gnueabi-gcc 02-fork_test.c -o 02-fork_test_arm.o

② 基于NFS文件系统,将可执行文件传到开发板上

cp 02-fork_test_arm.o /nfs_root/

③ 开发板上执行该程序测试,结果如下:

接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。

发布了261 篇原创文章 · 获赞 664 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/104847268