Linux进程之通过系统调用创建进程[fork()函数]

news2024/12/23 22:52:09

文章目录

  • 0.PID是什么?
  • 1.通过代码创建子进程--fork
    • 1.1fork()初识
    • 1.2通过系统调用创建进程
    • 1.3perror()函数的了解
  • 2.fork()的进一步了解
    • 2.1通过代码了解
    • 2.2查看进程的指令

0.PID是什么?

  • 进程PID(Process ID)是操作系统为每个正在运行的进程分配的唯一标识符
  • PID是一个整数值,用于在操作系统中唯一标识一个进程。每当一个新的进程被创建时,操作系统会为其分配一个唯一的PID。
  • PID在操作系统中起到了重要的作用,它可以用来识别和管理进程
  • 操作系统可以通过PID追踪进程的状态、资源使用情况、与其他进程的关系
  • PID还可以用于进程间通信、进程调度、资源分配等操作。
  • 在Linux中,进程PID的数据类型是pid_t,它定义在<sys/types.h>头文件中。pid_t类型是一个有符号整数类型[实际使用中,PID的值始终是非负整数]

1.通过代码创建子进程–fork

1.1fork()初识

在这里插入图片描述

输出
hello linux!
i love you!

int main()
{
printf("hello linux!\n);
printf("i love you!\n);
return 0;
}

输出
hello linux!
i love you!
i love you!

int main()
{
printf("hello linux!\n");
fork();
printf("i love you!\n");
return 0;
}

输出
hello linux!
ret = xxx
ret = 0

int main()
{
printf("hello linux!\n");
pid_t ret = fork();
printf("ret = %d\n", ret);
return 0;
}

1.2通过系统调用创建进程

在这里插入图片描述
在这里插入图片描述

成功 在父进程中返回子进程的PID,在子进程中返回0
失败 在父进程中返回-1,不创建子进程,适当设置errno

在这里插入图片描述
在这里插入图片描述

1.3perror()函数的了解

在这里插入图片描述

了解

  1. 打印与最近的错误代码相关的错误消息
  2. perror() 函数接收一个字符串参数 s,可以是自定义的错误提示信息
  3. 根据全局变量 errno 中保存的错误代码,将错误消息输出到标准错误流(stderr)

perror()函数的使用

  1. 在可能出错的操作后显示调用perror()函数
  2. perror()函数会检查 errno 的值,errno 是一个宏定义的全局变量,表示最近发生错误的错误代码
  3. 如果 errno 的值表示出现了错误,perror() 函数将根据 errno 的值输出相应的错误消息

举例:

    FILE *pfile = fopen("file.txt", "r");
    if (file == NULL)
    {
        perror("fopen");//输出: fopen: ...............
        return 1;
    }

2.fork()的进一步了解

2.1通过代码了解

  1. fork()之后 代码是父子共享的
  2. 虽然共享 但是通过if else 不一定都能执行 共享 != 能执行
int main()
{
pid t id = fork();
if(id< 0)
{
//创建失败perror ("fork") ;
return 1;
}
else if(id == 0)
{
//child process(task)
}
else
{
//parent process
}
printf("you can see me! n") ;
sleep(1);
return 0;
}

2.2查看进程的指令

1. 
ps axj  | head -1 && ps axj | grep test | grep -v grep
查看系统所有进程的信息只显示标题行
查看系统所有进程的信息只显示包含可执行程序test的内容
grep test 也是一个进程 为了显示只观 不显示 grep test 进程
2. 持续监控指定进程的脚本:
while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; echo "分隔符"; sleep 1; done

> 1. while :; 永远返回true 死循环
> 2. do 执行后面的语句
> 3. echo 的作用: 输出一行分隔符便于查看如"--------------------------"
> 4. sleep 1: 暂停1秒 便于查看

对下面代码的认识

  1. fork()之后有两个执行流 即两个进程
  2. 由此实现了两个死循环同时执行
  3. 以及if()else if() 同时执行 实际上是两个进程 判断了两次
int main()
{
pid t id = fork();
{
if(id< 0)
//创建失败
perror("fork") ;
return 1;
}
else if(id == 0)
{
//child process(task)while(1)
printf("I am child, pid: %d, ppid: %d\n", getpid(), getppid());
sleep(1);
}
else
{
//parentprocesswhile(1)
printf("I am father,pid: %d, ppid: %d\n", getpid(), getppid());
sleep(1);
}
return 0;
}

fork()函数返回值的认识

  1. 把子进程的pid返给父进程
  2. 把0返给子进程
  3. 父进程 : 子进程 == 1 : 0
  4. 把子进程的pid返给父进程 是为了让父进程能够对多个子进程进行管理
  5. 需要区分父子进程以进行分流操作

对子进程创建的认识

  1. fork()函数是OS提供的系统接口 由Linux内核实现
  2. 一个新的进程被创建 实际上就是OS多了一个进程
  3. 我们已知 每多一个进程 我们就要做相关的工作: a. 拷贝代码和数据至内存 b.建立PCB结构体
  4. 新进程的PCB实际上以父进程的PCB为模板[大部分相同 少部分是自己独有的 比如PID] 创建后加入到进程表 由操作系统进行管理

在这里插入图片描述

当fork()函数return后 核心代码执行结束了吗? 答案是: 已经执行完了

在这里插入图片描述

  1. 进程的调度: 在task_struct的队列中依据调度算法选择一个进程
  2. CPU运行队列根据不同的调度算法来确定进程的执行顺序,如先来先服务、短作业优先、时间片轮转
  3. 操作系统和cpu运行某一个进程,本质是从task_struct 形成的运行队列中按照调度算法挑选一个task_struct 来执行它的代码
  4. 把进程与进程对于的PCB–task_struct联系起来

进程列表和运行队列

  1. 进程表是操作系统中的数据结构,用于组织记录系统中所有进程的PCB。
  2. 每个进程都有一个对应的进程表项(PCB),包含进程的标识符、状态、优先级、资源使用情况等信息。
  3. 进程表可以用于管理和调度进程,操作系统可以根据进程表中的信息对进程进行分配资源、切换上下文等操作。
  4. CPU运行队列是操作系统中的一个数据结构,用于存放等待执行的进程
  5. 进程表是记录系统中所有进程的信息的数据结构 用于管理和调度进程
  6. CPU运行队列是存放等待在CPU上执行的进程的数据结构 用于确定进程的执行顺序

为什么会出现两个返回值?

  1. 子进程是在当前进程即父进程创建出来的
  2. 当子进程创建完 fork()函数准备return 之前 此时子进程已经被创建 当OS调度父进程时 父进程接收到的fork()函数的返回值id是已经创建好的子进程的pid 当子进程被调度 子进程接收到的fork()函数的返回值id是0 因为return id;语句被执行了两次 且是不同的值 所以才有了两个返回值的现象
  3. fork()函数内部 父子进程执行各自的return语句
  4. 返回两次 并不意味id有两个值
  5. 两个返回值返回到两个不同的进程
  6. 一个进程中只有一个确切的返回值

父子进程创建出来 谁先被运行呢?答案: 不一定

  1. 谁先运行不一定 由OS的调度器决定
  2. 比如: 当父进程执行了10ms 因为某些原因 父进程被放到运行队列的后面 OS又去执行子进程了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1205773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jquery的$

jQuery是什么 jQuery是一个快速、简洁的JavaScript框架&#xff0c;jQuery设计的宗旨是“write Less&#xff0c;Do More”。 jQuery的$ 使用过jQuery的应该都知道jQuery的$&#xff0c;看到源码中的这一段就能知道相当于jquery的简写&#xff0c; jquery有两种用法&#x…

Python 日志记录器logging 百科全书 之 日志回滚

Python 日志记录器logging 百科全书 之 日志回滚 前言 在之前的文章中&#xff0c;我们学习了关于Python日志记录的基础配置。 本文将深入探讨Python中的日志回滚机制&#xff0c;这是一种高效管理日志文件的方法&#xff0c;特别适用于长时间运行或高流量的应用。 知识点&…

【OS】操作系统课程笔记 第七章 内存管理

目录 7.1 内存管理的功能 7.1.1 内存分配 7.1.2 地址转换 1. 空间的概念 2. 地址转换 7.1.3 存储保护 7.1.4 存储共享 7.1.5 存储扩充 7.2 程序的链接和加载 7.2.1 程序的链接 链接的分类 7.2.2 程序的加载 1. 加载器的功能 2. 装入方式分类 7.3 连续分配方式 7.…

CentOS 7镜像下载;VMware安装CentOS 7;解决新安装的虚拟机没有网络,无法ping通网络的问题

CentOS 7镜像下载&#xff1b;VMware安装CentOS 8.5&#xff1b;解决新安装的虚拟机没有网络&#xff0c;无法ping通网络的问题 CentOS 8.5镜像下载VMware安装CentOS 7解决新安装的虚拟机没有网络&#xff0c;无法ping通网络的问题写入配置文件 CentOS 8.5镜像下载 阿里提供的…

排序 算法(第4版)

本博客参考算法&#xff08;第4版&#xff09;&#xff1a;算法&#xff08;第4版&#xff09; - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 本文用Java实现相关算法。 我们关注的主要对象是重新排列数组元素的算法&#xff0c;其中每个元素…

NSSCTF题库——web

[SWPUCTF 2021 新生赛]gift_F12 f12后ctrlf找到flag [SWPUCTF 2021 新生赛]jicao——json_decode() 加密后的格式 $json {"a":"php","b":"mysql","c":3}; json必须双引号传输 构造&#xff1a;GET里json{"x"…

【JUC】三、集合的线程安全

文章目录 1、ArrayList集合线程安全问题分析2、解决方式一&#xff1a;Vector或synchronizedList( )3、解决方式二&#xff1a;CopyOnWriteArrayList 写时复制4、HashSet集合线程不安全的分析与解决5、HashMap集合线程不安全的分析与解决 1、ArrayList集合线程安全问题分析 对…

TLP超线程技术

在实现IPL指令级并行的同时实现TLP(Thread Level Parallelism)线程级并行实现多线程有两种主要的方法超线程即同时多线程&#xff0c;在单个处理器或单个核中设置了两套线程状态部件&#xff0c;共享高速缓存和功能部件当两个线程同时需要某个资源时&#xff0c;其中一个线程必…

VuePress介绍及使用指南

VuePress是一个基于Vue.js的静态网站生成工具&#xff0c;它专注于以Markdown为中心的项目文档。VuePress具有简单易用的特性&#xff0c;同时提供了强大的自定义和扩展性。在本文中&#xff0c;我们将介绍VuePress的基本概念&#xff0c;并提供一个简单的使用指南。 什么是Vue…

【C语言】

C语言 1. C语言基础1.1 数据类型和占位符1.2 异或1.3 关键字1.4 const1.5 extern1.6 typedef1.7 static1.8 左值和右值1.9 位进行操作赋值 2. C指针3. 二维数组和指针4. 函数传递二维数组4.1 形参给出第二维的长度。4.2 形参声明为指向数组的指针。4.3 形参声明为指针的指针。 …

快速掌握队列的基础知识

目录 队列的特点基于链表实现队列用栈实现队列用队列实现栈 队列是一种线性数据结构&#xff0c;它只允许在一边进行插入操作&#xff08;队尾&#xff09;&#xff0c;另一边进行删除操作&#xff08;队头&#xff09;。插入操作称为入队&#xff0c;删除操作称为出队。队列遵…

【网络奇缘】我和英特网再续前缘

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络的概念 计算机网络的功能 ⭐1.数据通信 ⭐2.资源共享 ⭐3.分布式处理 ⭐4.提高可靠性 ⭐…

Java17新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…

Eclipse打包Springboot项目

首先&#xff0c;在pom.xml文件中添加配置&#xff0c;修改mainClass主函数&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configurat…

【电路笔记】-戴维南定理(Thevenin‘s Theorem)

戴维南定理&#xff08;Thevenin’s Theorem&#xff09; 文章目录 戴维南定理&#xff08;Thevenins Theorem&#xff09;1、概述与定义2、戴维南模型确定3、一些线性电路的戴维南模型3.1 单电压源3.2 单电流源3.3 多电流/电压源 4、结论 在本文中&#xff0c;我们将介绍一种强…

LLaMA模型之中文词表的蜕变

在目前的开源模型中&#xff0c;LLaMA模型无疑是一颗闪亮的⭐️&#xff0c;但是相对于ChatGLM、BaiChuan等国产大模型&#xff0c;其对于中文的支持能力不是很理想。原版LLaMA模型的词表大小是32K&#xff0c;中文所占token是几百个左右&#xff0c;这将会导致中文的编解码效率…

Python---综合案例:通讯录管理系统---涉及点:列表、字典、死循环

需求&#xff1a; 开个一个通讯录的管理系统&#xff0c;主要用于实现存储班级中同学的信息&#xff08;姓名、年龄、电话&#xff09; 涉及点&#xff1a;列表、字典、死循环 相关链接&#xff1a;Python--列表及其应用场景---增、删、改、查。-CSDN博客 Python---字典---…

ip数据包

数据报文格式 首部 版本&#xff08;Version&#xff09; 版本字段占4bit&#xff0c;通信双方使用的版本必须一致。对于IPv4&#xff0c;字段的值是4。 首部长度&#xff08;Internet Header Length&#xff0c; IHL&#xff09; 占4bit&#xff0c;首部长度说明首部有多少…

ubutun上编译出现undefined reference to symbol ‘dladdr@@GLIBC_2.2.5‘的错误

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> ubutun上编译一段C程序&#xff0c;出现错误&#xff1a; /usr/bin/ld: /tmp/ccghh3FJ.o: undefined reference to symbol ‘dladdrGLIBC_2.2.5’ //lib/…

前端---CSS的盒模型

文章目录 什么是盒模型&#xff1f;设置边框设置内边距设置外边距块级元素水平居中 什么是盒模型&#xff1f; 页面上的每个HTML元素都是一个一个的“盒子”&#xff0c;这些盒子由&#xff1a;内容、内边距、边框、外边距组成。 我们可以和住的房子联系起来&#xff0c;更好…