【Linux进程】查看进程fork创建进程

news2024/11/16 12:58:10

目录

前言

 1. 查看进程

 2. 通过系统调用创建进程-fork初识

总结


前言

         你有没有想过在使用Linux操作系统时,后台运行的程序是如何管理的?在Linux中,进程是一个非常重要的概念。本文将介绍如何查看当前运行的进程,并且讨论如何使用fork创建新的进程。通过了解这些内容,你将更好地理解Linux系统中的进程管理。

在这里插入图片描述

 1. 查看进程

          在理解进程状态之前,我们要先学会查看进程,进程的信息可以通过 /proc 系统文件夹查看 

 ls /proc

 可以看到有很多以数字命名的文件夹,这些数字其实就是进程的PID:

 进行实验的代码:

#include <stdio.h>
#include <unistd.h>
#include<sys/types.h>
 int main()
   {
         pid_t id = getpid();
         pid_t fid = getppid();
         while(1)
         {
             printf("Hello world! pid: %d ppid: %d\n",id,fid);                                                  
             sleep(1);
         }
  
         return 0;
  
  }

 指令:

 ls /proc/【PID】 -ld

 进一步查看进程详细信息:

ls /proc/【PID】 -l

 里边的文件都是进程的属性,这里有两个显眼的属性cwd和exe

  •  exe:进程可执行程序在磁盘中对应的位置
  •  cwd(current working directory):进程的当前工作目录

进程在运行时,它的可执行程序会被加载到内存当中,在进程运行的情况下我们依然可以删除它的可执行程序。删除之后再次查看运行中进程属性就会发现exe属性被标红且高亮闪烁

 在C语言中我们对文件进行操作:

fopen("file.txt" , " w");

这里也解释了,在没有这个文件时为什么会默认在程序的当前目录下创建。因为那是进程的工作目录;我们也可以通过修改进程工作目录的方式,改变创建文件的默认路径。

 我们可以调用chdir这个系统调用接口来改变进程的工作目录,以下时chdir的相关说明文档:

 使用时直接指定新路径即可,成功返回0,失败返回-1.

 实验代码:

int main()
{
    printf("self pid: %d\n", getpid());
    chdir("/home/test");

    FILE *fp = fopen("test.txt", "w");
    if(fp == NULL) return 1;

    fclose(fp);

    printf("新建文件完成\n");
    sleep(50); //50秒后结束运行,预留充足实际去查询进程

}

 在程序运行结束之前,查看进程的属性时发现,进程的工作目录被修改为了:/home/test

 程序运行结束之后发现test.txt文件出现在/home/test目录下。

 2. 通过系统调用创建进程-fork初识

 查看fork操作手册:

man fork

 退出时输入q即可

 man指令前边文章提到过,查看命令手册页的命令,在面对一个新的指令或者未知的指令我们都可以使用man查看,面对一些系统调用接口时也可以使用。

在查看时说明文档或许很长,我们如果是需要快速上手使用,可以主要看3部分:

  • synopsis (所属头文件、返回值类型)
  • description(接口基本功能)
  • return value (具体返回值)

fork基本信息:

  • 作用:创建一个子进程,
  • 返回类型:pid_t
  • 返回值:创建成功返回子进程的PID给父进程,返回0给子进程,失败返回-1给父进程

 我们可以实验一下:

实验代码:

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

int main()
{
   printf("before fork: I am a prcess, pid: %d, ppid: %d\n", getpid(), getppid());
 
   pid_t id = fork();
 
   printf("after fork: I am a prcess, pid: %d, ppid: %d, return id: %d\n", getpid(), getppid(), id);                                      
 
   sleep(2);
   return 0;
}

 运行结果:

 fork之后,运行了两次,原进程和子进程,fork之后代码共享,子进程会继承父进程大部分属性,子进程从fork之后执行

 原进程的父进程12333是谁? 其实是bash命令行解释器。

指令查看:

 ps ajx | grep pid

  •  为什么父进程返回子进程PID,子进程返回0 ?

        父进程与子进程的关系是1:n的关系,子进程有有唯一的父进程,而父进程为了辨别每个子进程就需要通过进程唯一的标识PID。

  • fork函数为什么会返回两次?

        fork函数功能是创建一个新的进程(子进程),子进程会继承父进程大部分属性,父进程调用fork函数执行到return时,子进程已经被创建,此时子进程继承了父进程状态,也是执行到return位置,父进程return一次,子进程return一次,所以它会执行两次。

  • id一个变量怎么可能同时大于0和等于0?

 进程在设计之初就被要求相互独立,互不影响,下面是一个测试样例:

父进程和子进程一起执行,使用kill指令发送信号杀死父进程,子进程不受影响依然可以运行。

 测试使用的指令:

while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done

 杀死进程:

kill -9 PID

 主要在进程运行界面杀死进程不能用ctrl c(会同时终止两个进程)。

 使用的代码

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

int main()
{
    printf("before fork: I am a prcess, pid: %d, ppid: %d\n", getpid(), getppid());

    sleep(5);
    printf("开始创建进程\n");
    sleep(1);
    pid_t id = fork();
    if(id < 0) return 1;
    else if(id == 0)
    {
        // 子进程
        while(1){
            printf("after fork, 子进程: I am a prcess, pid: %d, ppid: %d, return id: %d\n", getpid(), getppid(), id);
            sleep(1);
        }
    }
    else{
        // 父进程
        while(1){
            printf("after fork, 父进程: I am a prcess, pid: %d, ppid: %d, return id: %d\n", getpid(), getppid(), id);
            sleep(1);
        }
    }

    sleep(2);
    return 0;
}

 操作系统在设计进程之初就必须要考虑到进程相互独立这一点。

前边我们提到fork之后代码和数据共享,如果某一个进程修改了数据会不会对另一个进程造成影响?

        不会,操作系统为了使进程互不影响,某个进程(父进程或子进程)在修改数据时,操作系统会进行写时拷贝,进程修改数据时OS会单独开一块空间将数据复制一份交给(修改的数据)进程,修改数据也就是对新拷贝的数据进行修改。Linux中可以用同一个变量名,表示不同的内存空间。


总结

         进程是Linux操作系统中一个非常重要的概念,对于系统的管理和性能至关重要。通过本文的介绍,希望你对于Linux进程有了更深入的了解。在实际应用中,进程管理涉及到更多的细节和技巧。以上便是本文全部内容,希望对你有所帮助,感谢阅读!

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

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

相关文章

概率论与数理统计-第7章 假设检验

假设检验的基本概念 二、假设检验的基本思想 假设检验的基本思想实质上是带有某种概率性质的反证法&#xff0c;为了检验一个假设H0,是否正确&#xff0c;首先假定该假设H0正确&#xff0c;然后根据抽取到的样本对假设H0作出接受或拒绝的决策&#xff0c;如果样本观察值导致了…

【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(上)

HashMap工作原理全揭秘 — 核心源码解析 知识盲点概念介绍数据结构数组链表数组VS链表哈希表不同JVM版本HashMap的展现形式 HashMap VS HashTable特性区别对比 hashcodehashCode的作用equals方法和hashcode的关系key为null怎么办执行步骤 核心参数容量探讨负载因子探讨加载因子…

基于pytorch的循环神经网络情感分析系统

任务目标 基于给定数据集&#xff0c;进行数据预处理&#xff0c;搭建以LSTM为基本单元的模型&#xff0c;以Adam优化器对模型进行训练&#xff0c;使用训练后的模型进行预测并计算预测分类的准确率。 数据简介 IMDB数据集是一个对电影评论标注为正向评论与负向评论的数据集…

【Android开发】不同Activity之间的数据回传实例(一)摘桃子游戏

一、功能介绍 该项目实现的功能主要有&#xff1a; 在首页显示一个按钮点击该按钮跳转到桃园页面在桃园页面&#xff0c;点击桃子会弹窗显示摘到几个桃子&#xff0c;同时被点击桃子消失&#xff0c;总桃子数1点击退出桃园会返回首页&#xff0c;首页桃子数会根据点击的桃子数…

伐木工 - 华为OD统一考试

OD统一考试 题解: Java / Python / C++ 题目描述 一根X米长的树木,伐木工切割成不同长度的木材后进行交易,交易价格为每根木头长度的乘积。规定切割后的每根木头长度都为正整数,也可以不切割,直接拿整根树木进行交易。请问伐木工如何尽量少的切割,才能使收益最大化? 输…

一、docker的安装与踩坑

目录 一、安装docker&#xff08;centos7安装docker&#xff09;1.安装环境前期准备2.参考官网安装前准备3.参考官网安装步骤开始安装docker4.运行首个容器 二、安装一些软件的踩坑1.启动docker踩坑2.安装mysql踩坑3.罕见问题 三、关于我的虚拟机 一、安装docker&#xff08;ce…

销售团队如何实现业绩增长?CRM系统的线索管理功能有什么用?

随着“以客户为中心”观念的逐渐普及&#xff0c;销售团队的客户比过去更复杂&#xff0c;交易周期更久&#xff0c;竞争也更激烈。假如没有明确的销售计划&#xff0c;团队可能陷入混乱&#xff0c;最后导致客户&公司之间的负面结果。在这种情况下&#xff0c;人工智能驱动…

FineBI实战项目一(21):不同支付方式订单总额分析开发

点击新建组件&#xff0c;创建不同支付方式订单总额组件。 选择饼图&#xff0c;拖拽total_money到角度&#xff0c;拖拽pay_type到颜色&#xff0c;调节内径。 修改颜色的标识文字。 将组件拖拽到仪表板。 结果如下&#xff1a;

时至今日,编制与大厂到底怎么选?

我觉得这可能是一个辩论三天三夜也不会有结论的话题。 说实话&#xff0c;2023年已经过去&#xff0c;真的没有感觉赚钱更容易&#xff0c;反而是周边失业的同事不少。 现在感觉&#xff0c;是不是选择早点进入编制可能更加稳定&#xff1f;你们又怎么看&#xff1f;

Java中的多线程

进程和线程的概念 进程是应用程序的执行实例有独立的内存空间和系统资源。 线程是进程中执行运算的最小单位&#xff0c;可完成一个独立的顺序控制流程 一。一个进程可以包含多个线程&#xff0c;每个线程都独立执行特定的任务&#xff0c; 是CPU调度和分派的基本单位。 多线…

【AT 指令开发】软件框架与接口

目录 1 软件逻辑2.代码2.1 at_command.h2.2 at_command.c本文主要用于记录纯MCU无OS下,AT 指令开发软件框架 1 软件逻辑 2.代码 2.1 at_command.h #ifndef AT_COMMAND_H #define AT_COMMAND_Hvoid AT_CMD_Process(uint8_t *uartBuffer, uint8_t dataLen);/*描述AT指令返回值…

第二百五十九回

文章目录 知识回顾示例代码经验总结 我们在上一章回中介绍了MethodChannel的使用方法&#xff0c;本章回中将介绍EventChannel的使用方法.闲话休提&#xff0c;让我们一起Talk Flutter吧。 知识回顾 我们在前面章回中介绍了通道的概念和作用&#xff0c;并且提到了通道有不同的…

PyCharm中配置安装PyQt5、QtDesigner

PyCharm中配置安装PyQt5 使用 pip install PyQt5 命令安装。 安装pyqt5-tools&#xff1a;pip install pyqt5-tools 安装PyQt5Designer&#xff1a;pip install PyQt5Designer 上述三个都安装好之后&#xff0c;输入 pip list 查看一下 有如下内容就安装成功啦&#xff01;…

四、C++内存管理

1 C/C内存分布 在学习C的内存管理方式之前&#xff0c;我们先来看一道有关C/C内存分布的题目&#xff1a; 阅读下面的代码&#xff0c;回答相关问题&#xff1a; #include <iostream> using namespace std; int globalVar 1; static int staticGlobalVar 1; int main…

1.6计算机网络的性能指标

1.6计算机网络的性能指标 常用的计算机网络的性能指标有7个&#xff1a;速率、带宽、吞吐量、时延、往返时间、利用率、丢包率 1.6.1速率 计算机发送的信号是以二进制数字形式的。一个二进制数字就是一个比特(bit&#xff0c;binary digit)字节:Byte&#xff0c;1Byte8bit(1…

在海绵城市建设中,低功耗遥测终端有哪些独特的优势?

近年来&#xff0c;随着物联网技术的迅猛发展&#xff0c;数据监测和传输已经成为各行各业不可或缺的环节。在诸多特殊环境中因供电问题、潮湿、不便进入等诸多原因&#xff0c;需要一款功耗低、数据传输稳定&#xff0c;防潮抗锈蚀的低功耗遥测终端。 为满足这一需求&#xf…

太强了!腾讯开源!多模态AppAgent自主操作智能手机应用程序!

AppAgent是一款基于大型语言模型&#xff08;LLMs&#xff09;的新型多模态智能代理框架&#xff0c;专为操作智能手机应用而设计。它结合了GPT-4V的先进视觉理解能力&#xff0c;通过“眼睛”观察手机界面&#xff0c;模仿人类的点击和滑动交互方式来学习操作应用程序。这种方…

小红书种草类型有哪些,小红书营销攻略

我们都知道小红书是个内容平台。用户来这可以看到各种类型的笔记&#xff0c;从笔记中获取自己想要了解的内容。这也就意味着平台上有着许多种不同的笔记类型。今天我们和大家分享下小红书种草类型有哪些&#xff0c;小红书营销攻略&#xff01; 1. 明星带货类 顾名思义&#x…

vivado IP Revision Control

2020.2 只需要git 管理 prj.xpr 和 prj.srcs/ https://china.xilinx.com/video/hardware/ip-revision-control.html https://www.xilinx.com/video/hardware/vivado-design-suite-revision-control.html

网络编程的理论基础

文章目录 1 重点知识2 应用层3 再谈 "协议"4 HTTP协议4.1 认识URL4.2 urlencode和urldecode4.3 HTTP协议格式4.4 HTTP的方法4.5 HTTP的状态码4.6 HTTP常见Header4.7 最简单的HTTP服务器 3 传输层4 再谈端口号4.1 端口号范围划分4.2 认识知名端口号(Well-Know Port Nu…