liunx系统编程知识点

1.linux系统 内存管理

1、物理地址、线性地址(虚拟地址)和逻辑地址之间的关系
物理地址是指出现在cpu外部的地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。
逻辑地址是程序代码经过编译后在汇编程序中使用的地址。
线性地址又名虚拟地址,在32位cpu框架下,可以表示4G地址空间,用16进制表示就是0x00000000到0xffffffff。

在这里插入图片描述

2.内存管理
Linux内核的设计并没有全部采用Intel所提供的段机制,仅仅是有限度地使用了分段机制。这不仅简化了linux内核的设计,而且为把linux移植到其他平台创造了条件,因为很多RISC处理器并不支持段机制。
在linux中,所有段的基地址均为0,由此可以得出,每个段的逻辑地址空间范围是0-4GB。因为每个段的基地址为0,因此逻辑地址与线性地址保持一致(即逻辑地址的偏移量字段的值与线性地址的值总是相同的),在linux中所提到的逻辑地址和线性地址(虚拟地址),可以认为是一致的。看来,linux巧妙地把段机制给绕过去了,而完全利用了分页机制。

3.虚拟内存
Linux操作系统采用虚拟内存管理技术,使得每个进程都有一个独立的进程地址空间,该空间是大小为3G,用户所看到和接触的都是虚拟地址,无法看到实际的物理地址。利用这种虚拟地址不但能起到保护操作系统的作用,而且更重要的是用户程序可使用比实际物理内存更大的地址空间。

Linux将4G的虚拟地址空间划分为两个部分—用户空间和内核空间。用户空间从0到0xbfffffff,内核空间从3G到4G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间。例外情况是用户进程通过系统调用访问内核空间。
4.计算机系统组成
在这里插入图片描述
5.进程的数据结构
进程的静态描述:由三部分组成:PCB、有关程序段和该程序段对其进行操作的数据结构集。
进程控制块:用于描述进程情况及控制进程运行所需的全部信息。
代码段:是进程中能被进程调度程序在CPU上执行的程序代码段。
数据段:一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行后产生的中间或最终数据、
6.进程三态
就绪
等待(阻塞)
运行

①就绪(Ready)状态
当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态就称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将他们排成一个队列,称为就绪队列。
②执行状态
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
③阻塞状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

因创建而就绪,因调度而执行;因时间片用完而重新就绪;
执行中因I/O请求而阻塞;
I/O完成而就绪
注意:阻塞以后不能直接执行,必须进入就绪状态。
0号进程(也称为)空闲进程
1号进程 第一个用户进程。
7.fork
 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
 子进程与父进程的区别在于:
 1、父进程设置的锁,子进程不继承
 2、各自的进程ID和父进程ID不同
 3、子进程的未决告警被清除;
 4、子进程的未决信号集设置为空集。

**8.**fork系统调用
 包含头文件 <sys/types.h> 和 <unistd.h>
 函数功能:创建一个子进程
 函数原型
pid_t fork(void);
 参数:无参数。
 返回值:
 如果成功创建一个子进程,对于父进程来说返回子进程ID
 如果成功创建一个子进程,对于子进程来说返回值为0
 如果为-1表示创建失败

一次调用,两次返回,两次返回,是在各自的进程空间中返回的。
9.孤儿进程和僵尸进程
孤儿:如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程),如果父亲进程先结束,子进程会托孤给1号进程。

僵尸:如果子进程结束,父进程还没有查询子进程的状态,那么子进程就会是僵尸状态

避免僵尸进程
 调用wait或者waitpid函数查询子进程退出状态,此方法父进程会被挂起。
 如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出的时候向父进程发送的。

10.为什么网络协议栈需要放在内核中
主要是性能的考虑,因为这些资源比如ip并不是每个用户进程独享的。那么,如果不写到内核,就得有个独立的服务进程来处理相关逻辑。这时候某用户进程A做一个socket操作,就得先进内核做进程间通讯,然后上下文切到服务进程,然后再从那里进内核做IO,回来,再进内核做进程间通讯,再切回进程A。这个比起进程A直接进内核,做完回来,要慢太多了。

11.fork后父子进程共享文件描述符
2个进程共享了文件指针偏移量,所以都能向文件中有序写数据,需要加锁等方式来决定写入的顺序

12.fork与vfork
参考博客
https://blog.csdn.net/jianchi88/article/details/6985326

  1. fork ():子进程拷贝父进程的数据段,代码段
    vfork ( ):子进程与父进程共享数据段
  2. fork ()父子进程的执行次序不确定
    vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec 或exit 之后父进程才可能被调度运行。
    execve 用于调用其他应用程序

13.进程终止
https://blog.csdn.net/zt_xcyk/article/details/80620435

正常退出

 从main函数返回
 调用exit c库函数其中调用_exit exit(0);
 调用_exit 系统调用函数

 atexit可以注册终止处理程序,回调函数,退出时先注册的后执行 atexit(fun1);
 终止处理程序的调用与注册次序相反

异常退出
 调用abort() 产生SIGABOUT信号
 由信号终止 ctrl+c SIGINT

14.exec函数族
exec函数参数详解
https://www.cnblogs.com/invisible2/p/6647015.html

exec函数可以把当前进程替换为一个新进程。exec名下是由多个关联函数组成的一个完整系列,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。

15.wait和waitpid函数用法
 wait系统调用会使父进程暂停执行,直到它的一个子进程结束为止。
 返回的是子进程的PID,它通常是结束的子进程

Waitpid用来等待某个特定进程的结束

16.守护进程
https://blog.csdn.net/lianghe_work/article/details/47659889
是 Linux 中的后台服务进程
库函数daemon()可直接将进程变成守护进程

也可以自己实现守护进程
创建守护进程步骤
 调用fork(),创建新进程,它会是将来的守护进程
 在父进程中调用exit,保证子进程不是进程组组长
 调用setsid创建新的会话期
 将当前目录改为根目录 (如果把当前目录作为守护进程的目录,当前目录不能被卸载,它作为守护进程的工作目录了。)
 将标准输入、标准输出、标准错误重定向到/dev/null

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值