Linux基础-进程的超详细讲解(2)_进程的创建

news2025/1/12 16:16:01

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

Linux基础-进程的超详细讲解(2)_进程的创建与状态

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 通过系统调用创建进程-fork 

使用fork创建子进程

fork()的返回值: 

1. 在父进程中:

2. 在子进程中: 

创建多进程

进程的独立性:


1. 通过系统调用创建进程-fork 

使用fork创建子进程

在Linux系统下,可以使用man手册查看一个命令:

我们可以发现, fork需要包含两个头文件, 并且它的返回值是pid_t(也就是文件标识符)

那么我们可以写下这个代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int ret = fork();
    printf("hello proc : %d!, ret: %d\n", getpid(), ret);
    sleep(10);
    return 0;
}

输出结果如下:

我们可以发现, 由于fork()的作用, 程序在调用fork()后产生两个独立进程 (父进程和子进程). 这两个进程各自执行printf语句, 因此最终的输出将包含两行信息, 每行代表一个进程的输出.

根据程序的返回值我们可以发现:

1. 父进程执行fork():
父进程的PID是14792, 当调用fork()时, 它会创建一个新的子进程

在父进程中, ret的值是子进程的PID(14793), 因此打印出的内容是:

hello proc : 14792!, ret: 14793

 子进程执行fork():
子进程的ret值为0, 因为在子进程中, fork()返回值是0, 因此, 子进程打印的内容是:

hello proc : 14793!, ret: 0

fork()的返回值: 

1. 在父进程中:

fork()返回子进程的进程ID(PID), 这个pid是一个正整数, 表示创建的子进程的唯一标识符.

父进程可以跟踪和管理子进程

2. 在子进程中: 

fork()返回0, 这意味着子进程是父进程创建的, 并且它不需要关心其自身的pid.

返回0是fork()特有的行为, 以便子进程能够确认自己是新创建的进程. 

所以fork 之后通常要用 if 进行分流, 如下面代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{

    int ret = fork();
    if(ret < 0)
    {
        perror("fork");
        return 1;
    }
    else if(ret == 0)
    { //child
        printf("I am child : %d!, ret: %d\n", getpid(), ret);
    }
    else
    { //father
        printf("I am father : %d!, ret: %d\n", getpid(), ret);
    }
    sleep(1);
    return 0;

}

创建多进程

如下方代码所示: 

#include <iostream>
#include <vector>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

const int num = 10;

void SubprocessRun()
{
    while(true)
    {
        cout << "I am Sub process, pid : " << getpid() << "ppid: " << getppid() << std::endl;
        sleep(5);
    }
}

int main()
{
    vector<pid_t> allchild;
    for(int i = 0; i < num; i++)
    {
        pid_t id = fork();
        if(id == 0)
        {
            //子进程
            SubprocessRun();
        }
        //父进程
        allchild.push_back(id);
    }

        //父进程
        cout << "我所有的孩子是 : ";
        for(auto child : allchild)
        {
            cout << child << " ";
        }
        cout << endl;

        sleep(10);
        while(true)
        {
            cout << "我是父进程, pid : " << getpid() << endl;
            sleep(1);
        }
        return 0;
    }

编译完成后:

 运行结果:

在这个代码中, 让子进程陷入死循环, 一直打印子进程的pid和ppid, 父进程负责计入它的子进程

fork之后谁先运行由OS调度器自主决定!

进程的独立性:

 如下方代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int gval=0;

int main()
{
    printf("please Enter# ");
    scanf("%d", &gval);


    printf("gval: %d\n", gval);


    printf("I am a process, pid: %d, ppid: %d\n", getpid(), getppid());
    pid_t id = fork();
    if(id > 0)
    {
       while(1)
       {
           printf("我是父进程, pid: %d, ppid:%d, ret id: %d, gval: %d\n", getpid(), getppid(), id, gval);
           gval+=10;
           sleep(1);
       }
    }
    else if(id == 0)
    {
       while(1)
       {
           printf("我是子进程, pid: %d, ppid:%d, ret id: %d, gval: %d\n", getpid(), getppid(), id, gval);
           gval++;
           sleep(1);
       }
    }
    (void)id;
    printf("I am a 分支! pid: %d, ppid: %d\n", getpid(), getppid());
    sleep(1);
}

运行结果:

可以从上面的结果得出:

1. 独立的地址空间

每个进程都有自己的地址空间, 在fork()调用之后, 父进程和子进程的内存是独立的, 虽然代码开始时共享了全局变量gval的初始值, 但一旦它们各自开始执行并修改gval, 每个进程的gval实际上是独立的, 互不影响的

2. 数据的独立性

在这个程序中, 父进程和子进程在运行时会对gval进行不同的增量操作, 父进程将其增加到10, 子进程将其增加到1, 这说明, 尽管它们一开始有相同的gval值, 但随着程序的运行, 它们的gval值将会分别发生变化, 而不在互相影响.

3. 运行状态的独立性: 

父进程和子进程可以在不同的速度和时间点运行, 父进程的运行不会影响子进程(反之亦然)

 总结: 进程具有很强的独立性! 多个进程之间, 运行时, 互不影响, 即便是父子, 数据各自私有一份~

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

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

相关文章

Python从入门到高手6.4节-字符串格式化详解

目录 6.4.1 理解格式化 6.4.2 使用f-string进行格式化 6.4.3 使用格式化符号进行格式化 6.4.4 使用format方法进行格式化 6.4.5 上山打老虎 6.4.1 理解格式化 同学们比较熟悉的是磁盘格式化&#xff0c;将磁盘格式化以后&#xff0c;磁盘中的文件全部被清除。那么&#x…

数据湖新突破:Hudi让实时数据分析更高效!

开源数据湖对比 Hudi的使用收益 Hudi使用成效 Hudi内部机制 增量摄入与更新 Hudi使用一种混合日志存储模式(称为Copy-on-Write),可以同时处理基础数据文件(Parquet)和增量日志(HoodieLogFile)。以 MergeOnReadTable 的 upsert 操作为例,当有新数据到来时,Hudi会先将数据以行…

ubuntu 虚拟机将linux文件夹映射为windows网络位置

在使用虚拟机时可以选择将windows的文件夹设置为共享文件夹方便在虚拟机中访问windows中的文件,同理,也可以将linux的文件夹共享为一个网络文件夹,通过windows的添加一个网络位置功能,将linux的文件夹映射到windows本地,方便windows访问使用linux的文件夹 参照如下:https://blo…

CMA软件测评实验室如何申请|申请流程、筹备环节、材料清单、资源准备

CMA软件测评实验室资质的申请需要做好哪些准备工作&#xff1f;需要准备哪些材料&#xff1f;本文我们一起来梳理一下CMA软件测评实验室申请流程、准备环节、材料准备以及资源准备。 一、CMA软件测评实验室资质申请流程 1、申请资质认定的检验检测机构&#xff08;以下简称申…

使用OpenRewrite将Java自动升级到Java 21

使用 OpenRewrite 可以实现将Java 项目自动升级到Java 21语法。 基于Maven项目的实现步骤 步骤非常简单&#xff0c; 具体如下&#xff1a; 在pom.xml 中添加如下插件&#xff1a; <project><build><plugins><plugin><groupId>org.openrewri…

第90届CMEF进行中,飞凌嵌入式引领智慧医疗新潮流

2024年10月12日&#xff0c;第90届中国国际医疗器械博览会 (CMEF)在深圳国际会展中心(宝安)开幕&#xff0c;来自全球各地的4000多家展商齐聚一堂&#xff0c;为全球健康产业带来探析前沿、洞见未来的医疗盛宴&#xff0c;飞凌嵌入式在13号馆D01展位隆重亮相。 飞凌嵌入式作为…

经典文献阅读之--GMMCalib(使用基于GMM的联合配准进行激光雷达传感器的外部标定)

0. 简介 现有的激光雷达标定框架主要使用迭代最近点(ICP)及其变体等非概率配准方法。由于它们的成对配准过程以及对初始化和参数化的敏感性&#xff0c;这些方法的结果存在偏差。这通常会导致校准过程中的不校准。概率配准方法通过专门模拟观测值的概率性质来弥补这些缺点。《…

上市公司社会责任报告信息数据(纳税金额、社会捐赠等) 2007-2023年

一、数据指标&#xff1a; 股票代码 统计截止日期 公告日期 所属省份 行业代码 行业名称 纳税总额 每股社会贡献值 社会捐赠额 是否经第三方机构审验 审验机构 是否参照GRI《可持续发展报告指南…

PostGIS:道路网密度分析

道路网密度是评价城市道路网是否合理的基本指标之一,用道路网密度指标来描述区域内的道路长度及平均分布情况,体现城市道路供给水平,其具有统计简单、直观、数据容易获取的优点。另外,通过对不同等级道路网密度的统计还能很好地反映出城市道路等级结构关系,对于方格形城市…

让Activity更加优雅地跳转

公众号「稀有猿诉」 原文链接 让Activity更加优雅地跳转 有过Android开发经验的小伙伴对startActivityForResult以及onActivityResult一定不陌生&#xff0c;正是这一对API让组件 的复用变成可能。今天就来学习一下如何在函数式的范式中驾驭Activity的跳转。 缘起 系…

git的基本操作 + 分支管理

一、基本操作 1. 修改文件 Git比其他的版本管理器设计得更加优秀&#xff0c;因为Git追踪并管理的是修改&#xff0c;而非文件。 修改一个文件&#xff0c;不管你是添加一行&#xff0c;或者删除一行&#xff0c;还是添加了又删除了&#xff0c;甚至你创建了一个新文件&…

《CS:GO》的标志性实验地图在 RTX GPU 神经网络中运行

研究人员让标志性的《CS:GO》地图《Dust 2》完全通过神经网络在单个 RTX 3090 GPU 上模拟运行。 虽然这些片段既令人印象深刻&#xff0c;又问题百出&#xff0c;但它们展示了生成式人工智能在模仿全 3D 游戏环境方面取得的令人敬佩的进展。 该项目的负责人之一埃洛伊-阿隆索&a…

了解CRM外贸管理软件及其应用指南

在全球化的商业环境中&#xff0c;外贸活动显得尤为重要&#xff0c;而有效地管理这些活动则成为企业取得成功的关键之一。CRM外贸管理软件作为一种专门针对外贸企业设计的客户关系管理工具&#xff0c;近年来受到越来越多国际贸易公司的青睐。其中&#xff0c;Zoho CRM作为市场…

Java项目:157 基于springboot技术的美食烹饪互动平台的设计与实现(含论文+说明文档)

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本知识管理系统有管理员和用户两个角色 管理员权限操作的功能包括管理美食&#xff0c;对美食留言进行回复&#xff0c;管理美食知识信息&…

【QAMISRA】解决导入commands.json时报错问题

1、 文档目标 解决导入commands.json时报错“Could not obtain system-wide includes and defines”的问题。 2、 问题场景 客户导入commands.json时报错“Could not obtain system-wide includes and defines”。 3、软硬件环境 1、软件版本&#xff1a; QA-MISRA23.04 2、…

9.7 栅格图层符号化轮廓渲染

9.7 栅格图层符号化轮廓渲染_栅格构建轮廓-CSDN博客 目录 前言 轮廓 QGis设置为轮廓 二次开发代码实现轮廓 总结 前言 介绍栅格图层数据渲染之轮廓渲染说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 轮廓 以“3420C_2010_327_RGB_LATLNG.tif”数据…

UE小:UE5的Pixelstreaming在捕获画面的时候没办法显示非Viewport的Slate区域按钮的ToolTip

原始代码 首先&#xff0c;让我们看看原始代码片段&#xff1a; // Some widgets might want to provide an alternative Tooltip Handler. if (bCanSpawnNewTooltip || !NewTooltip) {TSharedPtr<SWidget> NewTooltipWidget NewTooltip ? NewTooltip->AsWidget()…

【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024

近期&#xff0c;阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM&#xff08;ACM国际多媒体会议&#xff09;是国际多媒体领域的顶级会议&#xff0c;旨在为研究人员、工程师和行业专家提供一个交流平台&#xff0c;以展示在多媒体领域的…

lstm基础知识

lstm前言 LSTM(Long short-term memory)通过刻意的设计来避免长期依赖问题&#xff0c;是一种特殊的RNN。长时间记住信息实际上是 LSTM 的默认行为&#xff0c;而不是需要努力学习的东西&#xff01; 在标准的RNN中&#xff0c;这个重复模块具有非常简单的结构&#xff0c;例…