![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux基础
文章平均质量分 74
Linux基础
ShenHang_
一个编程小菜鸡
展开
-
socket阻塞和非阻塞
socket阻塞和非阻塞有哪些不同1. 建立连接阻塞方式下,connect首先发送SYN请求到服务器,当客户端收到服务器返回的SYN的确认时,则connect返回,否则的话一直阻塞。非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回,返回的错误码为EINPROGRESS,表示正在进行某种过程。2. 接收连接阻塞模式下调用accept()函数,而且没有新连接时,进程会进入睡眠状态,直到有可用的连接,才返回。非阻塞模式下调用accept原创 2021-03-24 16:03:17 · 817 阅读 · 0 评论 -
linux socket IPC(本地套接字domain)
socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Sock原创 2020-06-26 21:50:40 · 628 阅读 · 0 评论 -
linux UDP实现广播和组播
广播广播很简单,原理不解释了,这里实现的重点在于:1.对服务器端的套接字使用setsockopt函数开放广播权限2.指定要发送的IP(广播地址)+端口号3.客户端必须显式绑定端口号(和2的端口号要一样)例子:server.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/socket.h>#include <string.h>#inc原创 2020-06-26 16:11:56 · 2060 阅读 · 1 评论 -
linux UDP的C/S模型
相较于TCP而言,UDP通信的形式更像是发短信。不需要在数据传输之前建立、维护连接。只专心获取数据就好。省去了三次握手的过程,通信速度可以大大提高,但与之伴随的通信的稳定性和正确率便得不到保证。因此,我们称UDP为“无连接的不可靠报文传递”。TCP面向字节流,UDP面向报文。那么与我们熟知的TCP相比,UDP有哪些优点和不足呢?由于无需创建连接,所以UDP开销较小,数据传输速度快,实时性较强。多用于对实时性要求较高的通信场合,如视频会议、电话会议等。但随之也伴随着数据传输不可靠,传输数据的正确率、传输顺原创 2020-06-25 22:36:30 · 242 阅读 · 0 评论 -
linux epoll反应堆模型
epoll反应堆模型的流程:epoll_create(); // 创建监听红黑树epoll_ctl(); // 向书上添加监听fdepoll_wait(); // 监听有客户端连接上来--->lfd调用acceptconn()--->将新创建的通信套接字的文件描述符cfd挂载到红黑树上监听读事件--->epoll_wait()返回--->cfd回调recvdata()--->将cfd摘下来监听写事件--->epoll_wait()返回--->cfd回调s原创 2020-06-25 15:23:36 · 358 阅读 · 0 评论 -
linux 基于网络C/S非阻塞模型的epoll ET触发模式(最常用的模型)
事件模型EPOLL事件有两种模型:Edge Triggered (ET) 边缘触发只有数据到来才触发,不管缓存区中是否还有数据。Level Triggered (LT) 水平触发只要缓存区中有数据都会触发。思考如下步骤:1.假定我们已经把一个用来从管道中读取数据的文件描述符(RFD)添加到epoll描述符。2.管道的另一端写入了2KB的数据3.调用epoll_wait,并且它会返回RFD,说明它已经准备好读取操作4.读取1KB的数据5.调用epoll_wait……在这个过程中,有两种工作原创 2020-06-24 16:59:31 · 316 阅读 · 1 评论 -
linux 多路IO转接服务器之epoll(重点)
epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。目前epell是linux大规模并发网络程序中的热门首选模型。epoll除了提供select/poll那种IO事件的电原创 2020-06-23 22:22:26 · 216 阅读 · 0 评论 -
linux 多路IO转接服务器之poll
#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout); struct pollfd { int fd; /* 文件描述符 */ short events; /* 监控的事件 */ short revents; /* 监控事件中满足条件返回的事件 */ };参数1是结构体数组的首地址。events的选取:POLLIN 普通或带外优先数据可读,即POLLRDNORM | POLL原创 2020-06-23 17:09:19 · 133 阅读 · 0 评论 -
linux 多路IO转接服务器之select
1.select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开的文件描述符个数并不能改变select监听文件个数2.解决1024以下客户端时使用select是很合适的,但如果链接客户端过多,select采用的是轮询模型,会大大降低服务器响应效率,不应在select上投入更多精力#include <sys/select.h>/* According to earlier standards */#include <sys/time.h>#i原创 2020-06-23 15:15:30 · 179 阅读 · 0 评论 -
linux 多进程/多线程并发服务器简单实现
首先补充一个关于read函数的点:如果顺利read()会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则说明读到了文件尾部。当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期。read 返回值:1.> 0实际读到的字节数2.= 0数据读完(读到文件、管道、socket 末尾–对端关闭)3.-1 异常3.1errno == EINTR 说明此调用被信号中断 重启/quit3.2errno == EAGAIN (原创 2020-06-22 11:04:00 · 390 阅读 · 0 评论 -
linux 网络编程之TCP的C/S模型
很多知识点都在计算机网络里学过了,就把自己觉得重要的点的再列一列。以太网帧格式数据链路层的以太网的帧格式如下所示:其中的源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位。显然,在数据帧传递的过程中,源MAC地址和目的MAC地址都是再不断变化的(数据帧到了某个路由器后,首先拆包到网络层,查看目的IP地址,结合路由选择算法确定下一跳的路由器IP,使用通过广播ARP请求分组获得下一跳路由器的MAC地址,获得下一跳的MAC地址后,结合当前路由器的MAC,重新组帧,最后把新的以太网数据帧发给原创 2020-06-21 11:32:58 · 396 阅读 · 0 评论 -
linux 多进程下semaphore实现哲学家用餐模型
多进程下也就说先要开辟个共享存储区实现进程间IPC,然后存储区里放的是5把锁即可。利用信号量机制实现。#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <stdlib.h>#include <semaphore.h>#include <sys/mman.h>#include <sys/wait.h>int main(void原创 2020-06-19 15:49:11 · 319 阅读 · 1 评论 -
linux 多线程下互斥锁实现哲学家用餐模型
#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <stdlib.h>pthread_mutex_t m[5];//定义5把锁//哲学家i左边的筷子编号为i,右边筷子编号为i+1void *tfn(void *arg){ int i, l, r; srand(time(NULL)); i = (int)arg; if (i == 4)//4号哲学家先拿原创 2020-06-19 15:30:36 · 552 阅读 · 0 评论 -
linux 对父子进程共享文件描述符的理解
父子进程共享文件描述符相当于2个fd指向同一块内存空间.因为2个进程共享了文件指针偏移量,所以都能向文件中有序写数据如果一个进程打开了一个文件以后,创建子进程,子进程会继承父进程的环境和上下文中的大部分内容,包括文件描述符。此时父子进程享有相同的文件偏移量,执行相同的程序读取文件中的字符。程序执行结果是随机的,可能是父进程先读,产生一个偏移,再由子进程读其相邻字符,也可能结果相反。例子:#include <stdio.h>#include <fcntl.h> //包含O原创 2020-06-18 17:17:59 · 3416 阅读 · 0 评论 -
linux 进程间同步
互斥量mutex进程间也可以使用互斥锁,来达到同步的目的。但应在pthread_mutex_init初始化之前,修改其属性为进程间共享。mutex的属性修改函数主要有以下几个。主要应用函数:pthread_mutexattr_t mattr 类型: 用于定义mutex锁的【属性】pthread_mutexattr_init函数: 初始化一个mutex属性对象int pthread_mutexattr_init(pthread_mutexattr_t *attr);pthread_mu原创 2020-06-18 16:52:08 · 554 阅读 · 3 评论 -
linux 多线程下使用semaphore实现“(多)生产者-(多)消费者”模型
信号量进化版的互斥锁(1 --> N)由于互斥锁的粒度比较大,如果我们希望在多个线程间对某一对象的部分数据进行共享,使用互斥锁是没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的目的,却无形中导致线程的并发性下降。线程从并行执行,变成了串行执行。与直接使用单进程无异。信号量,是相对折中的一种处理方式,既能保证同步,数据不混乱,又能提高线程并发。信号量基本操作(本质我觉得就是PV操作):sem_wait: 1.信号量大于0,则信号量-- (类比pth原创 2020-06-18 11:56:20 · 1356 阅读 · 1 评论 -
linux 线程同步之互斥锁、读写锁
线程同步举例: 内存中100字节,线程T1欲填入全1, 线程T2欲填入全0。但如果T1执行了50个字节失去cpu,T2执行,会将T1写过的内容覆盖。当T1再次获得cpu继续 从失去cpu的位置向后写入1,当执行结束,内存中的100字节,既不是全1,也不是全0。线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。因此,所有“多个控制流,共同操作一个共享资源”的情况,都需要同步。数据混乱原因:1.资源共享(独享资源则不会) 2.调度原创 2020-06-17 22:41:50 · 433 阅读 · 0 评论 -
linux 多线程下使用条件变量模拟“生产者-消费者”模型
我把理解全部写在代码注释里了。/*借助条件变量模拟 生产者-消费者 问题*/#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <stdio.h>/*链表作为共享数据,需被互斥量保护*/struct msg { struct msg *next; int num;};struct msg *head;/* 静态初始化 一个条件变量 和原创 2020-06-17 21:55:22 · 595 阅读 · 0 评论 -
linux 线程
线程LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下)进程:独立地址空间,拥有PCB线程:也有PCB,但没有独立的地址空间(共享)区别:在于是否共享地址空间。 独居(进程);合租(线程)。Linux下:线程:最小的执行单位进程:最小分配资源单位,可看成是只有一个线程的进程。Linux内核线程实现原理类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。1.轻量级进原创 2020-06-16 23:05:22 · 260 阅读 · 0 评论 -
linux 守护进程
终端:在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal),进程中,控制终端是保存在PCB中的信息,而fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。信号中还讲过,在控制终端输入一些特殊的控制键可以给前原创 2020-06-14 22:15:15 · 521 阅读 · 0 评论 -
linux SIGCHLD信号
SIGCHLD的产生条件子进程终止时子进程接收到SIGSTOP信号停止时子进程处在停止态,接受到SIGCONT后唤醒时借助SIGCHLD信号回收子进程子进程结束运行,其父进程会收到SIGCHLD信号。该信号的默认处理动作是忽略。可以捕捉该信号,在捕捉函数中完成子进程状态的回收。SIGCHLD信号注意问题1.子进程继承了父进程的信号屏蔽字和信号处理动作,但子进程没有继承未决信号集。2.注意注册信号捕捉函数的位置。3.应该在fork之前,阻塞SIGCHLD信号。注册完捕捉函数后解除阻塞。#i原创 2020-06-14 14:49:56 · 721 阅读 · 0 评论 -
linux 时序竞态
pause函数调用该函数可以造成进程主动挂起,等待信号唤醒。调用该系统调用的进程将处于阻塞状态(主动放弃cpu) 直到有信号递达将其唤醒。int pause(void); 返回值:-1 并设置errno为EINTR返回值:① 如果信号的默认处理动作是终止进程,则进程终止,pause函数没有机会返回。② 如果信号的默认处理动作是忽略,进程继续处于挂起状态,pause函数不返回。③ 如果信号的处理动作是捕捉,则调用完信号处理函数之后,pause返回-1,errno设置为EINTR,表示“被信号中原创 2020-06-13 20:22:38 · 260 阅读 · 1 评论 -
linux 信号2
sigaction函数修改信号处理动作(通常在Linux用其来注册一个信号的捕捉函数)int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 成功:0;失败:-1,设置errno参数:act:传入参数,新的处理方式。oldact:传出参数,旧的处理方式。struct sigaction结构体struct sigaction { void (*sa_handler原创 2020-06-13 17:16:10 · 499 阅读 · 0 评论 -
linux 信号1
信号的机制A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说,这个延迟时间非常短,不易察觉。每个进程收到的所有信号,都是由内核负责发送的,内核处理。与信号相关的事件和状态产生信号:1.按键产生,如:Ctrl+c、Ctrl+z、Ctrl+ \2.系统原创 2020-06-13 15:10:24 · 338 阅读 · 0 评论 -
linux 进程间通信-mmap
存储映射I/O存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中取数据,就相当于读文件中的相应字节。于此类似,将数据存入缓冲区,则相应的字节就自动写入文件。这样,就可在不使用read和write函数的情况下,使用地址(指针)完成I/O操作。使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过mmap函数来实现。mmap函数void *mmap(void *adrr, size_t length, in原创 2020-06-11 16:53:21 · 316 阅读 · 0 评论 -
linux 进程间通信-FIFO(有名管道)
FIFOFIFO常被称为命名管道,以区分管道(pipe)。管道(pipe)只能用于“有血缘关系”的进程间。但通过FIFO,不相关的进程也能交换数据。FIFO是Linux基础文件类型中的一种。但,FIFO文件在磁盘上没有数据块,仅仅用来标识内核中一条通道。各进程可以打开这个文件进行read/write,实际上是在读写内核通道,这样就实现了进程间通信。使用mkfifo函数创建FIFOmkfifo函数就是用于创建一个FIFO文件#include <sys/types.h>#include原创 2020-06-10 21:28:03 · 5339 阅读 · 0 评论 -
linux 进程间通信-pipe
IPC方法Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。现今常用的进程原创 2020-06-10 17:43:34 · 274 阅读 · 0 评论 -
linux wait、waitpid函数回收子进程
wait函数一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中使用echo $?命令查看,因为Shell是它的父进程,当它终止时Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。父进程调用wait函数可以回原创 2020-06-10 11:41:55 · 1190 阅读 · 0 评论 -
linux exec函数簇
fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。其实有六种以exec开头的函数,统称exec函数:int execl(const char *path, const char *arg, ...); //可变参数函数,即参数个数可变的函数。int ex原创 2020-06-09 21:09:09 · 473 阅读 · 0 评论 -
linux 系统编程-进程
CPU和MMU进程控制块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类型表示,其实就是一个非负整数。进程的状态,有就绪、运行原创 2020-06-09 17:21:48 · 215 阅读 · 0 评论 -
linux C库IO和系统IO
一、C库IO函数工作流程示意图:FILE 类型的指针,是特殊结构体类型,包含文件描述符、读写指针位置、内存地址等信息,用于文件读写操作。I/O缓冲区用于利用内存减少硬盘操作。在右侧三种情况下刷新缓冲区,存到硬盘上。二、进程控制块PCB和文件描述符文件描述符是int类型的。三、虚拟地址空间程序启动后,在磁盘上分配4G空间供进程使用,最多4G,用多少分多少。0-3G在用户区,程序员可操作;3-4G为内核区,程序员不可操作。受保护的地址(0-4K)也不许用户访问,如NULL在此区域。程序从ma原创 2020-06-08 21:30:07 · 384 阅读 · 0 评论 -
linux makefile
还是使用之前的例子生成可执行文件:gcc main.c ./src/*.c -I ./include -o myappgcc ./main.c ./src/*.c -I ./include -o ./myapp 不省略当前目录的写法(养成好习惯,给每个生成的文件合理存放,不然会很乱)这样太麻烦,所以要学makefilemakefile的规则:规则中的三要素: 目标, 依赖, 命令语法如下:目标:依赖tab命令vi makefile版本1(不会节省编译项目的时间,每次执行make原创 2020-06-06 21:28:47 · 140 阅读 · 0 评论 -
linux gdb调试
首先,先准备好代码,我以快排为例:把head.h,main.cpp,quicksort.cpp准备好。开始编译,生成可执行文件。注意,如果要进行gdb调试,必须加 -gg++ *.cpp -o myapp -g gdb myappgdb调试: 1. 启动gdb start -- 只执行一步 n -- 相当于step over s -- 相当于step into -- 可以进入到函数体内部 c 等价 continue -- 直接停在断点的位置 2原创 2020-06-06 15:55:50 · 190 阅读 · 1 评论 -
linux 动态库的制作和使用
step1.首先生成与位置无关的代码 (生成与位置无关的.o)gcc -fPIC -c *.c -I ../include/step2.生成动态库gcc -shared -o libMycalc.so *.o -I ../includemv libMycalc.so ../libstep3.用户结合main.c使用动态库、头文件进行编译,生成可执行文件1.gcc main.c ./lib/libMycalc.so -I ./include -o mysum2.gcc mai.原创 2020-06-05 17:03:24 · 391 阅读 · 0 评论 -
linux 静态库的制作和使用
制作流程:首先建立三个目录:include,lib,srcsrc用来存放所有的.c文件include用来存放所有的头文件lib用来存放静态库step1:在src目录下对*.c 进行处理,得到*.ogcc *.c -c -I ../include gcc 文件名1.c 文件名2.c 文件名3.c -c -I ../include step2:得到静态库 libMycalc.aar rcs libMycalc.a *.o 注意静态库的命名格式 lib静态库名.aar rcs lib.原创 2020-06-05 15:14:50 · 292 阅读 · 0 评论 -
linux gcc的编译过程
以head.h不在当前目录为例:原创 2020-06-04 23:03:49 · 157 阅读 · 0 评论 -
linux 进程管理
练习:查看当前在线用户的状况的命令whoLinux下如何切换设备终端?ctrl+alt+F1~F7Linux下各个设备终端之间是相互依赖的还是互不影响?互不影响写出命令,在终端下查看操作系统下所有的bash进程ps aux | grep "bash"如何使用kill命令查看信号编号?kill -l写出命令,杀死进程编号为998877的进程kill -9 998877查看当前进程环境变量的命令是哪一个?envenv | grep "PATH"..原创 2020-06-04 14:57:40 · 263 阅读 · 0 评论 -
linux 压缩包管理
练习:gzip命令能够对目录进行压缩吗?不能gzip命令对对文件压缩完毕之后会保留原文件吗?写出压缩的命令?不会gzip ./*.txt 压缩后的后缀都是.gzgzip命令对多个文件压缩之后会生成一个压缩包还是多个,都是什么格式的?多个,都是.gz格式bzip2命令能够对目录进行压缩吗?不能bzip2命令对对文件压缩完毕之后会保留原文件吗,如果能请写出该命令?可以bzip2 -k ./*.txtbzip2命令对多个文件压缩之后会生成一个压缩包还是多个,都是什么..原创 2020-06-04 14:33:15 · 184 阅读 · 0 评论 -
linux scp命令
sudo apt-get remove openssh-server 会删除软件包而保留软件的配置文件sudo apt-get remove openssh-server --purge 会同时清除软件包和软件的配置文件接下来看scp命令:注意:如果报错:scp 文件 : /目录: Permission denied这只是因为没有写入的权限,因此只需要修改本机文件夹的权限即可,使其对其他人拥有写入权限。...原创 2020-06-04 13:20:39 · 139 阅读 · 0 评论 -
linux ftp
sudo apt-get install vsftpdsudo vi /etc/vsftpd.conf 服务器端进行如下配置:sudo service vsftpd restart 配置完成后,重启服务客户端:1). 实名用户登录ftp IP(server的IP,ifconfig就可以找到)输入用户名(server上的用户)输入密码文件的上传和下载文件的上传: put 文件名 注意,在哪个目录下登录ftp服务器,就只能上传该目录下的文件到ftp,当然,文件上传的位置是原创 2020-06-03 11:47:31 · 172 阅读 · 0 评论