linux系统编程(七)进程(上)

简介: linux系统编程(七)进程

1.进程


1.1 进程相关概念


1.1.1 程序和进程


程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(cpu、内存、打开的文件、设备、锁…)

进程,是一个抽象的概念,与操作系统原理联系紧密。进程是活跃的程序,占用系统资源。在内存中执行。(程序运行起来,产生一个进程)


程序 → 剧本(纸) 进程 → 戏(舞台、演员、灯光、道具…)


同一个剧本可以在多个舞台同时上演。同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)

如:同时开两个终端。各自都有一个bash但彼此ID不同。


1.1.2 并发


并发,在操作系统中,一个时间段中有多个进程都处于已启动运行到运行完毕之间的状态。但,任一个时刻点上仍只有一个进程在运行。

例如,当下,我们使用计算机时可以边听音乐边聊天边上网。 若笼统的将他们均看做一个进程的话,为什么可以同时运行呢,因为并发。

1670988657615.jpg

分时复用cpu


1.1.3 单道程序设计


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


1.1.4 多道程序设计


在计算机内存中同时存放几道相互独立的程序,它们在管理程序控制之下,相互穿插的运行。多道程序设计必须有硬件基础作为保证。

时钟中断即为多道程序设计模型的理论基础。

并发时,任意进程在执行期间都不希望放弃cpu。因此系统需要一种强制让进程让出cpu资源的手段。时钟中断有硬件基础作为保障,对进程而言不可抗拒。

操作系统中的中断处理函数,来负责调度程序执行。 在多道程序设计模型中,多个进程轮流使用CPU (分时复用CPU资源)。而当下常见CPU为纳秒级,1秒可以执行大约10亿条指令。由于人眼的反应速度是毫秒级,所以看似同时在运行。

1s = 1000ms, 1ms = 1000us, 1us = 1000ns    1000000000


实质上,并发是宏观并行,微观串行! -----推动了计算机蓬勃发展,将人类引入了多媒体时代。


1.1.5 CPU和MMU


1670988847420.jpg

中央处理器(CPU)

1670988917777.jpg

内存管理单元MMU,linux系统内存空间为三级,内核为0级。分两级,windows是四种等级。

1670988931208.jpg


1.1.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类型表示,其实就是一个非负整数。
* 进程的状态,有就绪、运行、挂起、停止等状态。
* 进程切换时需要保存和恢复的一些CPU寄存器。
* 描述虚拟地址空间的信息。
* 描述控制终端的信息。
* 当前工作目录(Current Working Directory)。
* umask掩码。
* * 文件描述符表,包含很多指向file结构体的指针。
* 和信号相关的信息。
* 用户id和组id。
* 会话(Session)和进程组。
* 进程可以使用的资源上限(Resource Limit)。


1.1.7 进程状态


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

1670988967802.jpg

1.2 环境变量

环境变量,是指在操作系统中用来指定操作系统运行环境的一些参数。通常具备以下特征:
① 字符串(本质) ② 有统一的格式:名=值[:值] ③ 值用来描述进程环境信息。
存储形式:与命令行参数类似。char *[]数组,数组名environ,内部存储字符串,NULL作为哨兵结尾。
使用形式:与命令行参数类似。
加载位置:与命令行参数类似。位于用户区,高于stack的起始位置。
引入环境变量表:须声明环境变量。extern char ** environ;  
练习:打印当前进程的所有环境变量。             【environ.c】


1.2.1 常见环境变量


按照惯例,环境变量字符串都是name=value这样的形式,大多数name由大写字母加下划线组成,一般把name的部分叫做环境变量,value的部分则是环境变量的值。环境变量定义了进程的运行环境,一些比较重要的环境变量的含义如下:


环境变量相当于目录,环境变量的数值相当于对应页码

1670989001698.jpg

1.2.1.1 PATH


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

$ echo $PATH


1.2.1.2 SHELL


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


1.2.1.3 TERM


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


1.2.1.4 LANG


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


1.2.1.5 HOME


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


1.2.2 getenv函数


获取环境变量值

char *getenv(const char *name);  成功:返回环境变量的值;失败:NULL (name不存在)
练习:编程实现getenv函数。                【getenv.c】


1.2.3 setenv函数


设置环境变量的值  
int setenv(const char *name, const char *value, int overwrite);     成功:0;失败:-1
  参数overwrite取值:  
1:覆盖原环境变量 
0:不覆盖。(该参数常用于设置新环境变量,如:ABC = haha-day-night)


1.2.4 unsetenv函数


删除环境变量name的定义

int unsetenv(const char *name);  成功:0;失败:-1 
  注意事项:name不存在仍返回0(成功),当name命名为"ABC="时则会出错。


1.3 进程控制


1.3.1 fork函数


1670989082787.jpg

创建一个子进程。
pid_t fork(void); 
失败返回-1;
成功返回:① 父进程返回子进程的ID(非负)  ②子进程返回 0 
pid_t类型表示进程ID,但为了表示-1,它是有符号整型。(0不是有效进程ID,init最小,为1)
  注意返回值,不是fork函数能返回两个值,而是fork后,fork函数变为两个,父子需【各自】返回一个。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.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");
  exit(1);
  }else if(pid == 0)
  {
  printf("---child is create\n");
  }else if(pid > 0)
  {
  printf("---parent process:my child is %d\n",pid);
  }
  printf("=========================end of file \n");
  return 0;
}


1.3.1.1 循环创建n个子进程


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

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

1670989116704.jpg

循环创建N个子进程

从上图我们可以很清晰的看到,当n为3时候,循环创建了(2^n)-1个子进程,而不是N的子进程。需要在循环的过程,保证子进程不再执行fork

,因此当(fork() == 0)时,子进程应该立即break;才正确。


练习:通过命令行参数指定创建进程的个数,每个进程休眠1S打印自己是第几个被创建的进程。
如:第1个子进程休眠0秒打印:“我是第1个子进程”;第2个进程休眠1秒打印:
“我是第2个子进程”;第3个进程休眠2秒打印:“我是第3个子进程”。              
  【fork1.c】


通过该练习掌握框架:循环创建n个子进程,使用循环因子i对创建的子进程加以区分。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.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(5);
                printf("i'm parent \n");
        }else
        {
                sleep(i);
                printf("I'm %dth child\n",i+1);
        }
        return 0;
}
相关文章
|
11天前
|
Linux 应用服务中间件 Shell
linux系统服务二!
本文详细介绍了Linux系统的启动流程,包括CentOS 7的具体启动步骤,从BIOS自检到加载内核、启动systemd程序等。同时,文章还对比了CentOS 6和CentOS 7的启动流程,分析了启动过程中的耗时情况。接着,文章讲解了Linux的运行级别及其管理命令,systemd的基本概念、优势及常用命令,并提供了自定义systemd启动文件的示例。最后,文章介绍了单用户模式和救援模式的使用方法,包括如何找回忘记的密码和修复启动故障。
32 5
linux系统服务二!
|
11天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
39 4
linux进程管理万字详解!!!
|
11天前
|
Linux 应用服务中间件 Shell
linux系统服务!!!
本文详细介绍了Linux系统(以CentOS7为例)的启动流程,包括BIOS自检、读取MBR信息、加载Grub菜单、加载内核及驱动程序、启动systemd程序加载必要文件等五个主要步骤。同时,文章还对比了CentOS6和CentOS7的启动流程图,并分析了启动流程的耗时。此外,文中还讲解了Linux的运行级别、systemd的基本概念及其优势,以及如何使用systemd管理服务。最后,文章提供了单用户模式和救援模式的实战案例,帮助读者理解如何在系统启动出现问题时进行修复。
32 3
linux系统服务!!!
|
2天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
33 8
|
1天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
10 3
|
1天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
8 3
|
4天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
15 6
|
1天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
9 2
|
4天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
21 5
|
5天前
|
机器学习/深度学习 自然语言处理 Linux
Linux 中的机器学习:Whisper——自动语音识别系统
本文介绍了先进的自动语音识别系统 Whisper 在 Linux 环境中的应用。Whisper 基于深度学习和神经网络技术,支持多语言识别,具有高准确性和实时处理能力。文章详细讲解了在 Linux 中安装、配置和使用 Whisper 的步骤,以及其在语音助手、语音识别软件等领域的应用场景。
23 5