当前位置: 首页 > news >正文

查看进程,认识fork

知识点

1. getpid

  • 获取当前进程的进程ID(PID)。
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);

返回值:
成功:返回当前进程的PID(正整数)
失败:不会失败,始终成功

    示例

    #include <unistd.h>
    #include <stdio.h>
    
    int main() {
        pid_t pid = getpid();
        printf("My PID is %d\n", pid);
        return 0;
    }

    2. getppid

    • 获取当前进程的父进程ID(PPID)
    #include <sys/types.h>
    #include <unistd.h>
    
    pid_t getppid(void);
    
    返回值:
    成功:返回父进程的PID(正整数)
    失败:不会失败,始终成功
    特殊情况:若父进程终止,返回 1(init/systemd 进程的PID)

      示例

      #include <unistd.h>
      #include <stdio.h>
      
      int main() {
          pid_t ppid = getppid();
          printf("My parent's PID is %d\n", ppid);
          return 0;
      }

      3. fork

      • 创建一个子进程,子进程是父进程的副本(复制代码、数据、堆栈等)
      #include <sys/types.h>
      #include <unistd.h>
      
      pid_t fork(void);
      
      返回值:
      成功:
      在父进程中:返回子进程的PID(正整数)。
      在子进程中:返回 0。
      失败:返回 -1,并设置 errno(常见原因:系统进程数达到上限)。
      关键点:
      子进程从 fork 返回处开始执行,与父进程共享代码段。
      父子进程的执行顺序由调度器决定。
      子进程独立于父进程,修改变量互不影响(写时复制机制)。

        示例

        #include <unistd.h>
        #include <stdio.h>
        
        int main() {
            pid_t child_pid = fork();
        
            if (child_pid == -1) {
                perror("fork failed");
                return 1;
            } else if (child_pid == 0) {
                printf("Child process: My PID is %d, parent's PID is %d\n", getpid(), getppid());
            } else {
                printf("Parent process: My PID is %d, child's PID is %d\n", getpid(), child_pid);
            }
        
            return 0;
        }

        实操

        1 查看进程属性/信息两种方式

        创建一个进程

        #include <stdio.h>
        #include <unistd.h>
        
        int main()
        {
            while(1)
            {
                printf("Hello process\n");
                sleep(1);
            }
        
            return 0;
        }

        1 命令

        ps axj | head -1 && ps axj | grep myprocess | grep -v grep
        
        命令分解
        ps axj:显示所有进程的详细信息(包括无终端的进程)。
        head -1 && ps axj:只输出第一行(表头),方便查看列名。
        grep myprocess:筛选出包含 myprocess 的进程。
        grep -v grep:排除 grep 自身进程(避免干扰)

        显示:

        2 查看proc文件夹

        • 保存进程相关属性的目录,是一个内存及的文件系统,只有当操作系统启动的时候才会存在在磁盘上并不存在proc目录,我们刚刚创建好一个进程操作系统会自动在/proc目录下,为我们创建一个文件夹,以新增进程的PID命名
        ls /proc

        显示:

        ls /proc/1849822

         显示:

        2 认识fork(创建子进程)

        fork之后,创建了一个子进程,查看它们的pid

        #include <stdio.h>
        #include <sys/types.h>
        #include <unistd.h>
        
        int main()
        {
            printf("AAAAAAAAAAAA: pid: %d, ppid: %d\n", getpid(), getppid());
            fork();
            printf("BBBBBBBBBBBBBBBBBB: pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        
            return 0;
        }
        

        显示:

        父进程的ppid是bash

        ps axj | grep 1950019

        显示:

         3 fork有两个返回值,且地址一样(现象)

        #include <stdio.h>
        #include <sys/types.h>
        #include <unistd.h>
        
        int main()
        {
            printf("AAAAAAAAAAAA: pid: %d, ppid: %d\n", getpid(), getppid());
            pid_t ret = fork();
            printf("BBBBBBBBBBBBBBBBBB: pid: %d, ppid: %d, ret: %d, &ret: %p\n", getpid(), getppid(), ret, &ret);
            sleep(1);
        
            return 0;
        }
        

        显示:

         4 创建子进程代码

        #include <stdio.h>
        #include <sys/types.h>
        #include <unistd.h>
        
        int main()
        {
            pid_t ret = fork();
            if (ret == 0)
            {
                //子进程
                while(1)
                {
                    printf("我是子进程,pid:%d,父进程pid:%d\n", getpid(), getppid());
                    sleep(1);
                }
            }
            else if (ret > 0)
            {
                //父进程
                while(1)
                {
                    printf("我是父进程,pid:%d,父进程pid:%d\n", getpid(), getppid());
                    sleep(1);
                }
            }
            else //异常情况不考虑
            {}
        
            return 0;
        }
        

        显示

        5 父子进程有独立pcb,有独立性,因为代码共享而数据以写时拷贝的方式各自私有一份,保证两个进程不会互相干扰

        #include <stdio.h>
        #include <sys/types.h>
        #include <unistd.h>
        
        int main()
        {
            int x = 100;
            pid_t ret = fork();
            if (ret == 0)
            {
                //子进程
                while(1)
                {
                    printf("我是子进程,pid:%d,父进程pid:%d, %d, %p\n", getpid(), getppid(), x, &x);
                    sleep(1);
                }
            }
            else if (ret > 0)
            {
                //父进程
                while(1)
                {
                    printf("我是父进程,pid:%d,父进程pid:%d, %d, %p\n", getpid(), getppid(), x, &x);
                    x = 4321;
                    sleep(1);
                }
            }
            else //异常情况不考虑
            {}
        
            return 0;
        }
        

         显示

        http://www.dtcms.com/a/108745.html

        相关文章:

      • Python 设计模式:外观模式
      • 汽车 HMI 设计的发展趋势与设计要点
      • 《MyBatis CRUD实战与核心配置详解:从基础操作到高级应用》
      • Python入门(8):文件
      • SQL Server Integration Services (SSIS) 服务无法启动
      • I2C 读写 AT24C02
      • Genspark:重新定义搜索体验的AI智能体引擎
      • 循环结构- P1217-回文质数-第三十四天
      • 理解 Cookies:工作原理、类型与隐私安全指南
      • Spring 核心技术解析【纯干货版】- XIX:Spring 日志模块 Spring-Jcl 模块精讲
      • SQL Server:Log Shipping 说明
      • 位运算与集合
      • easyPan技术回顾day4
      • 【蓝桥杯刷题实战】路径之谜
      • APang网联科技项目报告【服务器篇】
      • Shell脚本中的日期变量详解
      • 理解Kotlin高阶函数:传递函数,而不是直接执行
      • 【C++11】异步编程
      • AI agent推理自私属性是否成为社会演化中的生存优势
      • 前端基础之《Vue(1)—简介》
      • 安装 AWS CLI
      • 在汇编层面理解MESI
      • win32汇编环境,网络编程入门之十八
      • 基于CNN-LSTM的深度Q网络(Deep Q-Network,DQN)求解移动机器人路径规划,MATLAB代码
      • RT-Thread 和 FreeRTOS 嵌入式实时操作系统对比
      • 嵌入式学习笔记——ARM
      • 科普:One-Class SVM和SVDD
      • 机器学习的一百个概念(9)学习曲线
      • RK3568下截屏工具weston-screenshooter
      • Oracle数据库数据编程SQL<6.3 获取用户、表名、表中文描述、列名、列中文描述、主键标识等完整信息>