首页 > 系统相关 >Linux 服务器开发基础学习笔记

Linux 服务器开发基础学习笔记

时间:2022-09-24 20:45:14浏览次数:55  
标签:返回 映射 int 笔记 环境变量 Linux 进程 服务器 id

Linux发展历史

1969 --unix 肯汤姆森 , C 丹尼斯里奇
商业:
- IBM
- APPLE
- 惠普
- sun
BSD:
- freeBSD
Linux:
- redhat centos
- debain ubuntu

MMU作用

虚拟内存和与物理内存的映射

设置修改内存的访问级别

访问级别:0 1 2 3 (由高到低) 由MMU设置访问内存访问级别 用户空间3级 内核空间0级

虚拟空间常用区域:
|=========
|
|内核区
|
|=========
|环境变量、命令行参数
|stack
|共享库
|.data .bss rw
|.text .rodata ro
|.head
|=========

用户空间:
进程间独立:单独开辟空间,MMU映射到不同空间

内核控件:
映射同一块空间

PCB 进程控制块

1、进程id:系统中每个进程都有一个id C语言中使用pid_t 类型描述
2、进程状态: 停止态 就绪态 运行态 挂起态 终止态 保存在PCB中
3、进程切换时需要保存和恢复的一些CPU寄存器
4、描述虚拟地址空间的信息 虚拟地址和物理地址对应信息
5、描述控制终端的信息
6、当前工作目录
7、umask掩码
8、文件描述符表,包含很多指向file结构体的指针
9、和信号相关的信息
10、用户id和组id
11、会话(Session)和进程组
12、进程可以使用的资源上限 ()

环境变量

环境变量 是指操作系统中用来指定操作系统运行环境的一些参数。通常具备以下特征:
1、环境变量一定是字符串
2、环境变量有统一的格式:[名]=:值 多个值用冒号分割
3、值用来描述进程环境信息
例如 输入date 由命令解析器调用 /bin/date
$PATH $SHELL $HOME $LANG $TERM 常用环境变量
环境变量的存储位置 和 命令行参数存储位置相近
存储形式 : char environ; 以NULL 作为哨兵结尾 使用 extern char environ;导出环境变量表
环境变量相关的函数
getenv() char
getenv(const char
name) 成功返回环境变量的值,失败返回NULL name不存在
setenv() int setenv(const char
name, const char
value, int overwrite); 成功返回0 错误返回-1
unsetenv() int unsetenv(const char* name); 删除环境变量

进程控制

函数fork()
pid_t fork(void) 创建一个子进程 读时共享,写时复制
返回值:普通函数一次调用返回一个值,
但是调用一次fork()返回俩个值:
1、返回紫禁城的pid (非负整数 > 0) 父进程的返回
2、返回0 子进程的返回
3、-1 时出错了

原理产生两个进程时 进程继续向后走; 父进程的fork返回子进程id 子进程返回0值
fork调用 一个进程 -> 两个进程

getpid()获取进程id getppid()获取父进程id 保证父进程晚点结束否则子进程会成为孤儿进程由root进程领养此时这个进程的父进程的id为1

进程共享

刚fork之后
父子相同处:全局变量,.data,.text,栈、堆、环境变量、用户id、宿主目录、进程工作目录、信号处理方式
父子不同处:进程id、fork返回值、父进程id、进程运行时间、闹钟(计时器)、未决信号集
读时共享,写时复制
父进程和子进程哪个先执行不确定取决于内核使用的调度算法

gdb调试

指令大全

============================================
run r 运行一个待调试的程序
continue c 让暂停的程序继续运行
next n 运行到下一行
step s 单步执行,遇到函数会进入
until u 运行到指定行停下来
finish fi 结束当前调用函数,回到上一层调用函数处
return return 结束当前调用函数并返回指定值,到上一层函数调用处
jump j 将当前程序执行流跳转到指定行或地址
print p 打印变量或寄存器值
backtrace bt 查看当前线程的调用堆栈
frame f 切换到当前调用线程的指定堆栈
thread thread 切换到指定线程
break b 添加断点
tbreak tb 添加临时断点
delete d 删除断点
enable enable 启用某个断点
disable disable 禁用某个断点
watch watch 监视某一个变量或内存地址的值是否发生变化
list l 显示源码
info i 查看断点 / 线程等信息
ptype ptype 查看变量类型
disassemble dis 查看汇编代码
set args set args 设置程序启动命令行参数
show args show args 查看设置的命令行参数

gcc main.c -g 得出的 a.out 才能调试
l (list) 列出代码
r (run) 执行
start 单步执行
set follow-fork-mode child 跟踪父进程(默认跟踪父进程)
set follow-fork-mode parent 跟踪子进程
一定要在fork之前调用

exec族函数

调用exec不会产生新的进程,不会产生新的进程id,旧程序被新进程替代 exec 函数族函数只有错误返回值,没有错误则执行完就结束,不会再执行调用函数
execlp 函数 加载一个进程 借助PATH环境变量
execl 函数 加载一个进程 通过路径+程序名来加载
execvp 函数 加载一个进程 使用自定义环境变量env

dup2

完成文件描述符的拷贝
|---|
| 1 |stdin
|---|
| 2 |stdout
|---|
| 3 |stderr
|---|
| 4 |file
|---|

dup2(2,3)
将2的付给3

孤儿进程和僵尸进程

孤儿进程:父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,则称init进程领养了子进程
僵尸进程:进程终止,父进程未对其进行回收,子进程残留资源(PCB)存放于内核中,变成僵尸进程,僵尸进程不能使用kill指令进行终止,因为僵尸进程已经结束。

wait() waitpid() 初步

pid_t wait(int *status)

父进程回收子进程终止信息。该函数有三个功能
1、阻塞等待子进程退出 父进程不会做其他事情
2、回收子进程残留资源 内核中不存在PCB
3、获取子进程结束状态 得到子进程如何回收的
wait 成功返回退出进程id 否则返回-1
wait(int *status) status是传出参数 获取子进程退出状态
通过宏获取状态
1、
WIFEXITED(status) 为非0 -> 进程正常结束
WEXITSTATUS(status)如上宏为真,使用此宏 ->获取进程退出状态
2、
WIFSIGNALED(status) 为非0 -> 进程异常终止
WTERMSIG(status)如上宏为真,使用此宏 ->取得使进程终止的那个信号的编号
3、
WIFSTOPPED(status)为非0->进程处于暂停状态
WSTOPSIG(status) 如上宏为真,使用此宏 ->取得使进程暂停的那个信号的编号
WIFCONTINUED(status)为真->进程暂停后已经继续运行

pid_t waitpid(pid_t pid, int* status, int options) 成功返回清理掉的子进程ID,成功返回-1
特殊参数和返回情况
参数pid:
>0 回收指定进程ID
-1 回收任意子进程(相当于wait)
0 回收和当前调用waitpid一个组的所有子进程
<-1 回收指定进程组的任意子进程
返回 0阻塞
WNOHANG(非阻塞 轮询) ,且子进程正在运行。
一次wait()或waitpid()调用只能清理一个子进程,清理多个子进程应使用循环。

IPC方法 进程间通信

1、管道 使用最简单
2、信号 开销最小
3、共享映射区 无血缘关系
4、本地套接字 最稳定

1、管道:

本质是伪文件
由两个文件描述符引用,一个表示读端,一个表示写端
规定数据从管道的写端流入管道,从读端流出
管道原理:管道实为内核使用环形队列机制,借助内核缓冲区4k
管道的局限性:
1、数据自己读不能自己写
2、数据一旦被读走,便不在管道中存在,不可反复读取
3、由于管道采用半双工通信方式,因此数据只能在一个方向上流动
4、只有在公共祖先的进程间使用管道

pipe 函数
int pipe(int pipefd[2]) 成功返回0 失败返回-1

fd[0] -> r
fd[1] -> w
关闭读端 close(fd[0]);

fifo 有名管道 用于非血缘关系进程间通信

2、共享内存:
创建共享内存的函数mmap函数
mmap函数

void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);

addr:简历映射区的首地址,由linux内核指定。使用时,直接传递NULL
length:欲创建映射区的大小
prot:映射区权限 PROT_READ、PROT_WRITE、 PROT_READ|PROT_WRITE
flags:标志位参数(常用于设定更新物理区域、设置共享、创建匿名映射区)
        MAP_SHARED:会将映射区所做的操作反映到物理设备(磁盘)上。
        MAP_PRIVATE:映射区所做的修改不会反映到物理设备上。
int munmap(void* addr, szie_t length);
fd:用来创建映射区的文件描述符
offset:映射文件的偏移(4k的整数倍)
返回值:  成功返回首地址,失败:MAP_FAILED宏

无法创建大小为0的共享空间
创建的文件必须大小不为0
借助共享内存访问磁盘文件 (之前 open write)

mmap 注意事项:
1、是否可以使用open O_CREATE创建缓冲区
不可以使用open O_CREATE创建缓冲区
因为创建出来的文件大小为0
但是不可以创建大小为0的缓冲区
但是可以创建大小为0的堆空间

2、(映射区首地址)mem++, munmap可否成功?
不能成功因为首地址不一样了
创建的映射区首地址和释放的映射区首地址要一样

3、如果open时O_RDONLY,mmap时PROT参数指定PROT_READ|PROT_WRITE会怎么样?
创建映射区的权限要小于等于打开文件的权限,映射区创建的过程中会产生一次对文件的读操作。

4、如果文件偏移量为1000会怎样?

offset(偏移值)的值必须为4k的整数倍
映射区内核MMU创建的,MMU映射时为4K

5、如果不检测mmap的返回值会怎么样?
会出错

6、mmap什么情况下会调用失败?
参数无效的情况下

7、对mem 越界操作会怎样?
无法munmap
无法释放

8、文件描述符先关闭对mmap映射有没有影响?
文件描述符先关闭没有影响
文件描述符就是操作一个文件的句柄,只要建立映射区成功就可以直接关闭。

父子进程或有血缘关系的进程之间使用共享内存

MAP_SHARED 父子共享
MAP_PRIVATE 进程独享

匿名映射区
不需要将东西写入文件 使用宏 MAP_ANONYMOUS(或MAP_ANOP) 这个宏只可以在linux下使用,其他类unix下不能使用
其他类Unix系统可以使用/dev/zero --- /dev/null
fd = open("/dev/zero",O_RDWR);

mmap 无血缘关系系进程间通信
使用同一文件创建映射区,
指定MAP_SHARED
可多读端多写端

标签:返回,映射,int,笔记,环境变量,Linux,进程,服务器,id
From: https://www.cnblogs.com/yangpj/p/16726535.html

相关文章

  • LINUX-第六章&第七章
    Linux笔记第六章&第七章20201303张奕博——————————————————————————————————————第七章文件操作五个级别硬件级别操作系统......
  • 关于 Linux 三个时间 atime、mtime、ctime
    三个时间Linux的文件属性中有:访问时间(AccessTime)、修改时间(ModifyTime)、改变时间(ChangeTime):访问时间(AccessTime):对文件进行一次读操作,它的访问时间就“有可能”会被......
  • COM组件 学习笔记
       COM组件是以Win32动态链接库dll或可执行文件exe的形式发布的可执行代码组成的;COM组件是动态链接的,COM使用dll将组件动态链接起来;COM组件是语言无关的;COM组......
  • linux微服务迁移
    shell脚本--拉取代码包背景:jenkins上线项目,更新项目包#!/bin/bash#====================================================#Description:UpdatethepackageforP......
  • C++自学笔记
    在C++中定义Definition一个类的时候要用分别的.h和.cpp文件去定义这个类.h和.cpp成对出现类的声明declaration和函数原型放在头文件里(.h)定义这些函数的结构主体就要放......
  • maven 学习笔记
    maven介绍1、是一个依赖管理工具2、自定义本地仓库例如:d:\javaStudy\maven20203、当项目使用时会首先检查本地是否存在,减少每次拉取远程仓库依赖包4、配置文件pom.xml......
  • Linux系统压测工具-Stress
    工具说明:stress是一个linux的压力测试工具,主要用来模拟系统负载较高时的场景,用于对系统的CPU、IO、内存、负载、磁盘等进行压力测试在线安装:执行命令yuminstall-yepel-......
  • 《计算机网络》第一章 笔记
    第一章概述互联网的两大特点:连通性与共享。1.互联网的概述1.1网络的网络计算机网络有若干节点(node)与连接这些节点的链路(link)组成。  其中,节点可以是计算机......
  • C++自学笔记 面向对象程序设计OOP(Object Oriented Programming)
    什么是对象?Objects=Attributes+ServicesData:ThepropertiesorstatusOperations:thefuctionsC语言中定义的变量用来存储数据,所以它可以理解为是“对象”“......
  • 海康摄像机使用GB28181接入SRS服务器的搭建步骤---封装docker镜像运行容器的方式,本篇
    使用第三方提供的镜像说明:这个是我在网上找的,没有实际验证及使用过,具体效果未知,看下文,我采用的是自己依据官方基础镜像进一步二次封装的镜像地址:https://hub.docker.com/......