1.目录结构

                                           /根

 bin           boot           etc             home        root       lib      val    ... 

命令         内核       配置文件                                      库

                                             stu        用户名(xiaoming)

                          main.c    mycode    桌面     ...

家目录:/home/stu                          /home/xiaoming

在当前目录下可以省略当前路径                   ./home == home

$普通(只在home中有权限)

#管理员   可切换:sudo su

2.常见操作:

cd ~ 切换到家目录
pwd 显示当前位置
ls 显示当前位置的文件
touch 创建普通文件 
mkdir 创建目录文件(文件夹)
cd . 当前
cd .. 上一层

3.文件类型:

- 普通文件
d 目录文件
p 管道文件
l 链接文件
c,b 设备文件
s 套接字文件

4.修改权限:

r    4   只读                       w   2   只写                  x   1   执行

      u      g      o

-   rwx   rwx  r-x       

  若要修改权限:

修改权限:
chmod u-x a.txt
chmod g-w a.txt
chmod o+w a.txt   

修改为: - rw- r-x rwx 

按照权值修改(数字设定法)
chmod 657 a.txt  

5.文件复制粘贴移动:

cp:   a.c    b.c        cp: -r mydir1 mydir2       目录文件 -r     cp:   ../b.c    .  相对路径绝对路径均可

rm:   a.c b.c   一次可以删除多个    rm: -r mydir2   目录文件 -r 

mv: a.c temp  移动(ctrl+v)  目录文件不用 改名字 mv: a.c b.c(将a.c 改为b.c)

6.VIM使用:

命令模式  ——————插入模式——————末行模式

1->2:i,a,o,I,A,O

2->1:Esc

1->3:(输入冒号):

命令模式:

r 修改一个字符    R替换,Esc结束
C 大写,清除光标到行末的内容
cc  清除光标所在的一行的内容,并进入插入模式
x   删除一个字符

末行模式:

wq:退出并保存
q!:退出不保存
q:只退出,前提是未修改文件
w:只保存不退出
set nu   显示行号   set nonu  取消行号
:n  跳转到第n行
gg 跳转到第一行    G 跳转到文件末尾
n yy   复制n行            n dd  剪切/删除n行
p粘贴    u :撤销    ctrl + r 恢复一次操作


?从后往前搜索    /从前往后搜索
/末行模式搜索,n在多个搜索到的位置切换
set hlsearch   设置高亮       set  nohlsearch  取消高亮

gcc -o main main.c        生成可执行程序main   运行程序必须写全部路径

cat   a.c     将文件打到屏幕上(文件内容少)

cat   b.c    main.c  > flie1   也可以合并文件

cat >aa.txt      写入文件  ctrl d 退出

more passwd 分屏显示,不可反复看

less passwd 可以反复看,分屏显示,q退出

tail/head  -3 passwd 显示末尾(开头)几行    默认十行

find 路径 -name 文件名  在系统内查找

grep "hello" main.c   文件查找字符串

-i   不区分大小写        -c   显示有几行        -v  取反   -w  绝对查找     -e 查找多个

l 管道              top 显示终端(每隔一秒刷新)运行     q退出

进程:一个正在运行的程序(操作系统)

管理进程:   讲述描述符|进程控制块|PCB

命令解释器(shell):bash

kill + pid 结束一个正在运行的程序             ctrl + c  可以结束一个前台运行的进程

kill -9  pid  强制结束                                    -e  (所有)    -f(fu进程)

ps  -ef    (竖线) grep "sleep"

sleep 300 & 放后台,不影响其他命令

jobs   只显示后台运行任务  包括(任务号)

bg %任务号(前台切后台,先停止)   fg %任务号(后台切前台)       ctrl + z  停止在前台运行的进程

man 帮助手册 :

1.命令 2.系统调用 3.库函数

关机重启:

tar cvf xx.tar a.c passwd    -->打包并命名为xx.tar

解压:

tar zxf xx.tar.gz

运行级别:   3级别,文本方式,无图形化界面    5级别,图形界面

由源文件  ———>可执行文件  : 预编译--编译--汇编--链接

                                                        -E         -S       -c      -o

makefile文件 ,管理工程,实现自动化的编译

linux 调试程序:   GDB命令调试          开发调试版本 -g          gcc -o test test.c -g

l  显示代码
b + 行号   加断点
info break  显示断点信息
display i(一直显示i的值)
r  启动程序
p  打印
q  退出
c  继续运行
s  进入函数
finsh  跳出函数
bt  显示当前位置,展示函数的层层位置
ldd  查看可执行程序用到哪些共享库

库文件 ,静态库 ,共享库 (动态链接库)

printf() 库函数
stdio.h   -->声明          libxx.a   静态库  :C语言,预先编译好的方法的集合
c库文件                    libxx.so  共享库  : 
生成静态库 : ar crv libfoo.a add.o max.o
生成共享库 : gcc -shared -fPIC -o libfoo.so add.o max.o
(须把生成的libfoo.so移动到/lib中才能运行,默认在/lib中寻找库)  /lib,/usr/lib
使用库foo : gcc -o main main.c -L.(路径名) -lfoo(库名)
 

 静态库和共享库的区别:

  • 静态库:编译时合并代码到可执行文件,生成独立程序。优点:部署简单,无外部依赖。缺点磁盘和内存占用大,库更新后需重新链接。

  • 共享库:编译时只记录依赖,运行时动态加载。优点:节省磁盘和内存,库更新后重启即可生效。缺点:部署依赖目标系统有正确版本的库,版本不兼容可能导致运行失败。

int main(int argc ,      char* argv[] ,      char* envp[])    有三个参数

               参数个数            参数                   环境变量         argv[0] 是程序名称或路径

printf   -->  在缓冲区存储(由内核打印到屏幕)     可以强行刷新缓冲区输出到屏幕上

1.    "/n"      2.fflush(stdout)    

exit(0)   ->强行输出         _exit(0)  ->不输出

fork:通过复制当前进程来创建一个子进程

fork  的写时拷贝:子进程创建时并不立即复制父进程的物理内存,而是与父进程共享同一份内存并将页面设为只读;当父子任意一方试图修改内存数据时,操作系统才会为该页面真正分配独立空间并复制内容,提升 fork 效率并节省内存,以页为单位拷贝

推迟内存的拷贝(复制),甚至免除

在子进程中:  pid = 0;
在父进程中:  pid = 子进程的pid  > 0
子进程是父进程的副本,但拥有独立的 PID,其余完全相同,仅在fork后接着运行
父子进程同时执行,顺序不确定
父进程的父进程为bash  -->好多进程的父进程
父进程一结束就会有提示符
先fork 拷贝,复制    -->   在进行exec替换

僵死进程:子进程先于父进程结束,父进程没有获取子进程的退出码,那么子进程变成僵死进程

孤儿进程:父进程先结束,子进程会被重新分配新的父进程,然后在正常wait

解决方法:父进程调用wait()    -->阻塞父进程,子进程结束后再运行父进程

若不采用此,需将退出码右移八位

程序中打印的都是逻辑地址,相对于起始地址的偏移量

文件描述符:open read write close 等方法

1.打开文件   2.读/写    3.关闭文件           

stdin 标准输入 -->0     stdout 标准输出 -->1   stderr  标准错误输出 -->2   默认打开这三个

file.txt  -->3(自己创的)...

先fork,在打开文件  -->  父子进程有各自的偏移量
先打开文件,在fork  -->  偏移量父子进程共享,同时移动文件偏移量

                 同一个偏移量                                     父子进程各自的偏移量

替换  :  execl ---- >最终都通过 execve 系统调用实现

成功之后  -->不会返回(原进程的代码段已被替换,不可能再执行 exec 之后的代码)

系统调用:

应用程序调用 open() 库函数时,会先将系统调用号 5 存入 eax 寄存器,然后通过 int 0x80 指令触发软中断,从用户空间切换到内核空间;内核根据 eax 中的编号 5 查表,找到并执行对应的内核函数 sys_open(),完成文件打开操作;执行完毕后,内核恢复现场并返回用户空间,最终将返回值传递给应用程序。

系统调用和库函数的区别:

系统调用是操作系统内核提供的底层接口,运行在内核态,用于访问硬件 / 系统资源,开销大、不可移植;库函数是编程语言 / 第三方库提供的封装函数,运行在用户态,通常会封装系统调用,开销小、可移植。

exec  -->替换:  没有本质区别,只是传参不同     底层调用execve

fork + exec   产生全新进程

fun 函数是由操作系统内核在信号发生时**自动调用**并传入信号编号作为参数的,而不是由代码直接调用的,所以不需要传参,只是注册了一个函数。

内核会在信号发生时自动传参。(收到信号才会传参)

kill可以执行信号的代号,通过传参,但是kill 9 不可改变,强制杀死

  • kill(pid, sig):向进程号为 pid 的进程发送编号为 sig 的信号

  • 成功返回 0,失败返回 -1

父进程通过忽略 SIGCHLD 信号,可以让子进程退出后被系统自动回收,避免产生僵尸进程

进程间通信(IPC):管道,信号量,共享内存,消息队列,套接字

>写入管道的数据再内存中,速度快<   

通信方式:半双工           此外还有单工,全双工(电话)

创建管道文件  mkfifo,成对出现

1.无名管道:只能用于父子进程或兄弟进程等有亲缘关系的进程   fd[0] 读  fd[1] 写

2.有名管道:可以用于任意两个进程,但需要两个进程同时打开(一个读,一个写)同时操作

管道为空,读操作read()阻塞;管道为满,写操作write()阻塞

关闭写端,read返回值为0;关闭读端,write出发异常(产生信号) //SIGPIPE (13)

信号量同步操作:             0.1二值信号量   3,计数信号量

ipcs  介绍信号量,在运行中可以看到,结束后看不到
ipcrm -s  id   删除信号量

PV操作:两个信号量控制读写一致

【进程间通信(IPC)】函数:

                            shmctl                                                       semctl

并发运行:交替运行          并行:两条线程同时运行

消息队列:

普通消息类型必须 > 0,若type = 0,则不区分消息类型,都可以接收  线程结束对主线程没有影响但主线程结束,其余线程都会结束。可以使用join阻塞,等待线程结束

  • 原子操作:不可拆分、中途不能被打断;i++ 不是原子操作,底层分读、改、写三步,多线程会互相抢数据、算错值。会导致输出数据与预期不匹配。
  • 数据竞争:多线程同时改同一个共享变量,不加锁就会结果错乱、数值偏小。                       也可以malloc一个内存空间,存储该线程的变量,让主线程变量的修改不会影响该线程。
  • 互斥锁:同一时间只让一个线程进代码段,把多步操作变成逻辑不可打断,解决数据竞争和打印乱序。
  • 打印不出 01234 原因:主线程循环跑得太快,子线程启动有延迟,共用同一个循环变量 i,读到的都是被改后的旧值。多个线程抢一个i变量。
  • 解决办法:给每个线程单独传参,不共用变量;多线程操作共享数据必须加锁,还要用 pthread_join 等线程跑完再退出。

本程序设有2个生产者线程、3个消费者线程,生产者向环形缓冲区放入数据,缓冲区满则阻塞;消费者从缓冲区取出数据,缓冲区空则阻塞,借助信号量实现同步、互斥锁实现临界资源互斥访问,生产与消费总数量相等,线程安全有序运行。先同步,后互斥。

线程,进程内部的一条执行路径    //进程,一个正在运行的程序    //调度,执行的基本单位

(linux多线程及线程同步的方法)

线程同步的方法:互斥锁,信号量,读写锁,条件变量 

线程安全:无论调度顺序如何,都能得到正确的结果

创建线程,管理员在内核完成,可以使用多个处理器

多线程的程序执行fork后,子进程只有一条执行路径,fork所在的那条执行路径(线程)

使用线程安全函数:如,将strtok -->strtok_r

必须先执行服务器,在执行客户端,否则链接不成功,在客户端不强调必须绑定(ip+port)

TCP 面向连接可靠的流式服务,UDP 无连接高效快速但不可靠

套接字文件 sockfd = 3           文件类型      在int c = 4,文件类型

                      三次握手                                              四次挥手

为什么不是两次?

  • 两次握手会有 “半连接” 风险:如果客户端的 SYN 包延迟到达,服务器收到后回复 SYN+ACK,但客户端早已超时重连,服务器会一直等待 ACK,浪费资源。
  • 第三次握手本质是让客户端确认服务器的接收能力正常,只有客户端确认收到了服务器的 SYN,连接才正式建立。

  • 为什么挥手要四次? 因为 TCP 是全双工的,双方都可以独立发送数据:

    • 客户端发 FIN,只是表示 “我不发数据了”,但还能接收数据
    • 服务器回复 ACK 后,可能还有数据要发给客户端,所以服务器的 FIN 必须等自己的数据发完再发,这就把 “服务器确认客户端 FIN” 和 “服务器发 FIN” 分成了两步,所以总共四次。
  • 为什么客户端要等 2MSL(2分钟)? -->(time wait存在的意义)

    • 确保服务器收到了客户端的 ACK:如果服务器没收到 ACK,会重发 FIN,客户端在 2MSL 内还能收到并重发 ACK
    • 防止旧连接的报文干扰新连接:2MSL 可以让本次连接的所有报文都在网络中消失,避免后续新建连接时收到旧数据

connect之后开始握手,在接受和发送数据之前

套接字:点分十进制的IP地址+端口号

netstat -natp : 查看本机所有 TCP 连接(监听 / 已连),用数字 IP 端口,同时显示是谁(哪个进程 / 程序)在占用

tcp:可靠性,应答确认,超时重传,可以去重,乱序重排。面向字节流,但会发生粘包问题(粘包:对方发送的多个报文,被一次性收到了):1.加起始结束标记 2. 使用固定长度的报文3. 报头中包含数据的长度。tcp使用滑动窗口,可以进行流量控制//(通信双方都有发送缓冲区接收缓冲区),点对点连接

udp协议:编程流程 ,无连接,不可靠,数据报服务,不用建立链接,所以可以把客户端或者服务端关闭之后在开启也可以发送,无粘包,发送一次,能接受多少传多少,下一次重新开始

tcp和udp可以使用同一个窗口:会根据自己各自的协议进行区分

  • 端口只是逻辑编号TCP、UDP 是两套独立协议
  • 系统内核根据协议 + 端口区分数据,不会混包

访问服务器不传参,默认为/index.html                  /favicon.ico为网站的图标

lseek,设置鼠标偏移量的移动(也可以求文件大小)

  • strcat:只能拼固定字符串,不能用变量 / 数字。
  • sprintf:能拼数字、变量,支持格式化拼接。

一、基础网络协议(HTTP/HTTPS)

  1. 层级与端口
    • HTTP:应用层协议,默认端口 80
    • HTTPS:加密版 HTTP,默认端口 443
  2. DNS 解析:域名(如www.baidu.com)通过 DNS 解析转换成服务器 IP 地址,浏览器才能发起连接。
  3. HTTP 与 HTTPS 核心区别
    • HTTP:明文传输,数据无加密,存在窃听、篡改风险
    • HTTPS:基于 TLS 加密传输,数据安全,防止窃取与篡改
  4. HTTP 两种请求方法 GET / POST
    • GET:参数拼在 URL,明文可见,适合查询数据,有长度限制
    • POST:参数放在请求体,隐藏传输,适合提交表单、上传数据,无硬性长度限制
  5. HTTP 响应状态码
    • 1xx:信息类(接收请求,继续处理)
    • 2xx:成功(200 OK 请求正常处理)
    • 3xx:重定向(跳转新地址)
    • 4xx:客户端错误(404 页面不存在、403 权限拒绝)
    • 5xx:服务端错误(500 服务器内部异常)

二、浏览器与 TCP 服务器通信流程

  1. 浏览器调用connect()发起 TCP 三次握手,和服务器(IP + 端口)建立 TCP 连接;
  2. 浏览器发送HTTP 请求报文给服务器;
  3. 服务器解析请求,构造HTTP 响应报文返回浏览器;
  4. 两种 TCP 连接模式:
    • 短连接:一次请求响应完成后,调用close()直接断开 TCP 连接;
    • 长连接(HTTP1.1 默认):连接不断开,复用同一条 TCP 通道完成多次请求 - 响应交互,减少反复握手开销。
  5. 底层依托 TCP 服务器承载上层 HTTP 协议,TCP 负责可靠数据传输,HTTP 规定数据格式。

三、前端网页基础三剑客

网页由三类文件配合渲染:

  • HTML:页面骨架文档,搭建文字、图片、链接等基础结构
  • CSS:页面布局美化,控制颜色、尺寸、排版样式
  • JS:页面交互脚本,实现点击、动画、数据交互等动态功能

select 是 Linux 早期 IO 多路复用接口,靠位图 fd_set 管理待监控文件描述符,可单线程监控多个套接字。 它通过四个宏操作位图,函数能监控读、写、异常三类 IO 事件,支持设置阻塞超时。 调用时 fd 集合会被内核修改,需要备份集合循环复用;返回值区分事件就绪、超时、报错三种情况。 TCP 服务端用它同时监听新连接和客户端数据读写。 缺点是最多监控 1024 个 fd,每次调用要拷贝集合、内核遍历全部 fd,并发高性能差,只适合少量连接场景。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐