Linux下的系统编程——进程(七)

前言:

程序是指储存在外部存储(如硬盘)的一个可执行文件, 而进程是指处于执行期间的程序, 进程包括 代码段(text section) 和 数据段(data section), 除了代码段和数据段外, 进程一般还包含打开的文件, 要处理的信号和CPU上下文等等.下面让我们开始对Linux进程的学习吧

一、进程的概念:

1.程序与进程区别:     

程序:死的。只占用磁盘空间。        ——剧本。

进程;活的。运行起来的程序。占用内存、cpu等系统资源。    ——戏。

2.并发:

        并发,在操作系统中,一个时间段中有多个进程都处于已启动运行到运行完毕之间的状态。但,任一个时刻点上仍只有一个进程在运行。
        例如,当下,我们使用计算机时可以边听音乐边聊天边上网。若笼统的将他们均看做一个进程的话,为什么可以同时运行呢,因为并发。

 3.单道程序设计:

        所有进程一个一个排对执行。若A阻塞,B只能等待,即使CPu处于空闲状态。而在人机交互时阻塞的出现时必然的。所有这种模型在系统资源利用上及其不合理,在计算机发展历史上存在不久,大部分便被淘汰了。

4.多道程序设计:

        在计算机内存中同时存放几道相互独立的程序,它们在管理程序控制之下,相互穿插的运行。多道程序设计必须有硬件基础作为保证。
        时钟中断即为多道程序设计模型的理论基础。并发时,任意进程在执行期间都不希望放弃cpu。因此系统需要一种强制让进程让出 cpu资源的手段。时钟中断有硬件基础作为保障,对进程而言不可抗拒。操作系统中的中断处理函数,来负责调度程序执行。
        在多道程序设计模型中,多个进程轮流使用CPU(分时复用CPu资源)。而当下常见CPu为纳秒级,1秒可以执行大约10亿条指令。由于人眼的反应速度是毫秒级,所以看似同时在运行。
        1s = 1000ms, 1ms = 100Ous,1us = 1000hs       1000000000 
实质上,并发是宏观并行,微观串行!         ----推动了计算机蓬勃发展,将人类引入了多媒体时代。

5.CPU和MMU:


虚拟内存与物理内存映射关系

6.进程控制块PCB:

        我们知道,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。
        /usr/src/linux-headers-3.16.0-30/include/linux/sched.h.文件中可以查看struct task_struct结构体定义。其内部成员有很多,我们重点掌握以下部分即可:·

    本质:结构体    

    进程id,系统中每个进程有唯一的id,在C语言类型中用pid_t类型表示,其实就是一个非负整数

    文件描述符表

    进程状态:  初始态、就绪态、运行态、挂起态、终止态。

    进程工作目录位置

    *umask掩码 (不是最重要的)

    信号相关信息资源。

    用户id和组id

7.进程状态:

        进程基本的状态有5种。分别为初始态,就绪态,运行态,挂起态与终止态。其中初始态为进程准备阶段,常与就绪态结合来看。

二、环境变量:

1.PATH:

        可执行文件的搜索路径。ls命令也是一个程序,执行它不需要提供完整的路径名/bin/ls,然而通常我们执行当前目录下的程序a.out却需要提供完整的路径名.l/a.out,这是因为PATH环境变量的值里面包含了ls命令所在的目录/bin,却不包含a.out所在的目录。PATH环境变量的值可以包含多个目录,用:号隔开。在shell 中用echo命令可以查看这个环境变量的值:

        $echo  $PATH

2.SHELL:

        当前Shell,它的值通常是:  /bin/bash

3.TERM:

        当前终端类型,在图形界面终端下的值通常是xterm。终端类型决定了一些程序的输出显示方式,比如图形界面终端可以显示汉字,而字符终端一般不行。

4.LANG.

         语言和 locale,决定了字符编码以及时间、货币等信息的显示格式。

5.HOME

        当前用户主目录的路径,很多程序需要在主目录下保存配置文件,使得每个用户在运行该程序时都有自己的一套配置。

三、进程控制

 1.fork(重点):

    pid_t fork(void)

    创建子进程。父子进程各自返回。父进程返回子进程pid。 子进程返回 0.

    getpid();getppid();

    循环创建N个子进程模型。 每个子进程标识自己的身份。
 

       (1) fork函数原理:

        (2)创建子进程

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int main(int argc,char *argv[])
{printf("before fork -1-\n");printf("before fork -2-\n");printf("before fork -3-\n");printf("before fork -4-\n");pid_t pid = fork();if(pid == -1){perror("fork error !\n");exit(1);}else if(pid == 0){printf("child is created\n");}else if(pid > 0){printf("parent process : my child is %d\n",pid);}printf("end of file\n");return 0;
}

  

        循环创建n个子进程

    一次fork函数调用可以创建一个子进程。那么创建N个子进程应该怎样实现呢?简单想

        for(i= 0; i< n; i++)fork()}即可。但这样创建的是N个子进程吗?
 

 

 

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int main(int argc,char *argv[])
{int i;pid_t pid;for(i = 0;i < 5;i++){if(fork() == 0)break;}if(i == 5)printf("I'm parent \n");elseprintf("I'm %dth child\n",i+1);return 0;
}

 

CPU抢夺现象:

如果出现3这种情况,说明子进程没有抢过bash进程,没有争过bash的CPU

避免父进程超越子进程的办法:

增加一个sleep进行延时打印父进程


#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int main(int argc,char *argv[])
{int i;pid_t pid;for(i = 0;i < 5;i++){if(fork() == 0)break;}if(i == 5){sleep(2);printf("I'm parent \n");}else{sheep(i);printf("I'm %dth child\n",i+1);}return 0;
}

2.getpid和getppid:

getpid():获取当前进程ID

​ pid_t getpid(void);

getppid 函数:获取当前进程的父进程 ID

​ pid_t getppid(void);

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int main(int argc,char *argv[])
{printf("before fork -1-\n");printf("before fork -2-\n");printf("before fork -3-\n");printf("before fork -4-\n");pid_t pid = fork();if(pid == -1){perror("fork error !\n");exit(1);}else if(pid == 0){printf("child is created,pid = %d,parent-pid:%d\n",getpid(),getppid());}else if(pid > 0){printf("parent process : my child is %d,my pid :%d,my parent_pid:%d\n",pid,getpid(),getppid());}printf("end of file\n");return 0;
}

四、进程共享 

        父子进程之间在 fork后。有哪些相同,那些相异之处呢?

        刚fork 之后: 
        父子相同处:全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...


        父子不同处:

        1.进程ID                        2.fork返回值              3.父进程ID             

        4.进程运行时间             5.闹钟(定时器)           6.未决信号集
l
      似乎,子进程复制了父进程 0-3G 用户空间内容,以及父进程的 PCB,但 pid 不同,真的每fork一个子进程都要将父进程的 0-3G 地址空间完全拷贝一份,然后在映射至物理内存吗?

      当然不是!  父子进程间遵循读时共享写时复制的原则。这样设计,无论子进程执行父进程的逻辑还是执行自己的逻辑都能节省内存开销。


重点注意!        躲避父子进程共享全局变量的知识误区
【重点】:父子进程共享:

        1.文件描述符(打开文件的结构体)

        2. mmap建立的映射(进程间通信详解)

特别的,fork之后父进程先执行还是子进程先执行不确定。取决于内核所使用的调度算
法。

 

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

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

相关文章

Java运行时jar时终端输出的中文日志是乱码

运行Jar时在控制台输出的中文日志全是乱码&#xff0c;这是因为cmd/bash默认的编码是GBK&#xff0c;只要把cmd的编码改成UTF-8即可 两种方式修改&#xff1a;临时修改和注册表永久修改 临时修改 只对当前的cmd页面有效&#xff0c;关闭后重新打开都会恢复成GBK, 打开cmd&am…

【数据结构】十字链表的画法

十字链表的基本概念 有向边又称为弧 假设顶点 v 指向 w&#xff0c;那么 w 称为弧头&#xff0c;v 称为弧尾 顶点节点采用顺序存储 顶点节点 data&#xff1a;存放顶点的信息firstin&#xff1a;指向以该节点为终点&#xff08;弧头&#xff09;的弧节点firstout&#xff1…

gRPC之gRPC认证

1、gRPC认证 前面篇章的gRPC都是明文传输的&#xff0c;容易被篡改数据&#xff0c;本章将介绍如何为gRPC添加安全机制。 gRPC默认内置了两种认证方式&#xff1a; SSL/TLS认证方式 基于Token的认证方式 同时&#xff0c;gRPC提供了接口用于扩展自定义认证方式。 1.1 TLS…

Redis 教程 - Redis 基本操作

Redis 教程 - Redis 基本操作 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的内存数据库&#xff0c;它提供了键值对存储和多种数据结构的支持&#xff0c;被广泛应用于缓存、消息队列、计数器等场景。本教程将介绍 Redis 的基本操作&#xff0c;包括连接…

001_C++语法基础

C++语法基础 所有C++语法要用英文区分大小写每个语句写完以分号结束C++标准输入输出头文件iostream 若想通过C++实现数据的输入和输出,需要导入标准输入输出头文件 #include <iostream>标准输入输出头文件<iostream>中包含了cin输入语句和cout输出语句 标准命名…

想系列服务迁移专有云效实操

想系列服务迁移专有云效实操 1注册应用 查看jenkins脚本是否需要修改代码编译路径 gemdale_jenkins/maven3-service/k8s-image/maven3-service-deploy.sh Jenkins上的打包路径 service_tgt_path s e r v i c e w s / t a r g e t / service_ws/target/ servicew​s/target/ser…

前端三大Css处理器之Less

Less是Css预处理器之一&#xff0c;分别有Sass、Less、Stylus这三个。 Lesshttps://lesscss.org/ Less是用JavaScript编写的&#xff0c;事实上&#xff0c;Less是一个JavaScript库&#xff0c;他通过混合、变量、嵌套和规则设置循环扩展了原生普通Css的功能。Less的少数…

k8s之存储篇---存储类StorageClass

介绍 StorageClass 为管理员提供了描述存储"类"的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略&#xff0c;或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为"配置文件&quo…

Unity3D Pico VR 手势识别

视频链接 本文章使用的 Unity3D版本: 2021.3.6 , Pico SDK 230 ,Pico OS v.5.7.1 硬件Pico 4 Pico SDK可以去Pico官网下载SDK 导入SDK 第一步&#xff1a;创建Unity3D项目 第二步&#xff1a;导入 PICO Unity Integration SDK 选择 Windows > Package Manager。 …

vue3路由跳转以及传参。和vue2路由跳转传参的区别

路由的安装和引入以及注册就不过多赘述&#xff0c;直接说区别和怎么跳转页面 vue2路由跳转以及传递参数 vue2只需要创建好router文件夹和index.js&#xff0c;配置好我们的路由&#xff0c;在main.js引入 import router from "/router"; // vue路由app.use(route…

【ES6】—类与继承

一、 定义类 class People {constructor (name, age) {this.name namethis.age age}showName () {console.log(this.name)} } let p1 new People(xiaoxiao, 30) console.log(p1) // People {name: xiaoxiao, age: 30}小节&#xff1a; 使用class关键字声明类使用construc…

linux离线安装rdbtools,需先安装python

离线安装python3 下载python包&#xff0c;下载地址&#xff1a;https://www.python.org/ftp/python/ 我选的是https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz 将文件上传至linux服务器&#xff0c;解压 tar -xf Python-3.9.0.tgz cd Python-3.9.0 mkdir /usr/l…

Golang参数输入

Golang参数输入 1.命令行参数&#xff08;os.Args&#xff09; package mainimport ("fmt""os""strconv" )func main() {for i, num : range os.Args[1:] {fmt.Println("参数"strconv.Itoa(i)": ", num)} } //输入&#x…

时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测

时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测 目录 时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测&a…

XSS漏洞及复现

一、什么是XSS 跨站脚本( Cross-site Scripting )攻击&#xff0c;攻击者通过网站输入框输入payload(脚本代码 )&#xff0c;当用户访问网页时&#xff0c;恶意payload自动加载并执行&#xff0c;以达到攻击者目的( 窃取cookie、恶意传播、钓鱼欺骗等)为了避免与HTML语言中的C…

沉浸式VR虚拟实景样板间降低了看房购房的难度

720 全景是一种以全景视角为特点的虚拟现实展示方式&#xff0c;它通过全景图像和虚拟现实技术&#xff0c;将用户带入一个仿佛置身其中的沉浸式体验中。720 全景可以应用于旅游、房地产、展览等多个领域&#xff0c;为用户提供更为直观、真实的体验。 在房地产领域&#xff0c…

深入了解Docker镜像操作

Docker是一种流行的容器化平台&#xff0c;它允许开发者将应用程序及其依赖项打包成容器&#xff0c;以便在不同环境中轻松部署和运行。在Docker中&#xff0c;镜像是构建容器的基础&#xff0c;有些家人们可能在服务器上对docker镜像的操作命令不是很熟悉&#xff0c;本文将深…

Kuka机器人设计通用码垛程序

假设需要一个码垛程序, 从输送线抓到托盘, 托盘每层4个, 需要码5层, 可以用以下程序架构设计: 1, 再config中定义层数cengshu , 每层码垛的个数(码垛的次数)cishu , 每层的高度levelHeight , 码垛放置点的集合putPoint[,] ,预放点1集合prePut1[,], 预放点2集合prePut2[,] DEC…

git常用场景记录 | 拉取远程分支A合并到本地分支B

文章目录 git常用场景记录拉取远程分支A合并到本地分支B本地分支B存在未add与commit的代码 git常用场景记录 doing&#xff0c;最后更新9.1 拉取远程分支A合并到本地分支B 需求描述 在团队合作时&#xff0c;我自己的本地分支B功能已经实现并合并到feature&#xff0c;之后发现…

ssm园区停车管理系统源码和论文

ssm园区停车管理系统源码和论文104 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#x…