![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux
文章平均质量分 74
Y~哈哈哈
这个作者很懒,什么都没留下…
展开
-
Linux中线程安全问题
一、线程安全的介绍 在目前的计算机科学中,线程是操作系统调度的最小单元,进程是资源分配的最小单元。在大多数操作系统中,一个进程可以同时派生出多个线程。这些线程独立执行,共享进程的资源。在单处理器系统中,多线程通过分时复用技术,处理器在不同的线程间切换,从而更高效地利用系统 CPU资源。在多处理器和多核系统中,线程实际上可以同时运行,也就是每个处理器可以运行一个线程,系统的运算能力相对于...原创 2019-05-17 21:53:58 · 774 阅读 · 0 评论 -
中断和处理
一、中断中断本质上是一种特殊的电信号,由硬件设备发向处理器。处理器接受到中断后,会马上向操作系统反映此信号的到来,然后就由操作系统负责处理这些新到来的数据。硬件设备生成中断的时候并不考虑与处理器的时钟同步,换句话说就是中断随时可以产生。因此,内核随时可能因为新到来的中断而被打断不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标志。二、中断处理程序在响应一个特定中断的时...原创 2019-05-08 21:41:21 · 642 阅读 · 0 评论 -
系统调用二
关于系统调用地举例:https://blog.csdn.net/YL970302/article/details/85677588一、与内核通信系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个:(1)它为用户空间提供了一种硬件的抽象接口。举例来说,当需要读写文件的时候,应用程序就可以不去管磁盘类型和介质,甚至不用去管文件所在的文件系统到底是哪种类型(2)系统...原创 2019-05-08 21:40:37 · 203 阅读 · 0 评论 -
进程间关系
一、进程间关系1、进程组Linux下每个进程都隶属于一个进程组,因此它们除了PID信息外,还有进程组ID(PGID)。用下面这个函数来获取指定进程PGID#include<unistd.h>pid_t getpgid(pid_t pid);该函数成功时返回进程pid所属进程组的PGID,失败则返回-1,并设置errno。每个进程都有一个首领进程,其PGID和P...原创 2019-04-24 22:49:16 · 495 阅读 · 0 评论 -
两种高效的事件处理模式——Reactor和Proactor模式
I/O模型中的同步和异步的区别?区分是内核向应用程序通知的是何种I/O事件(就绪事件还是完成事件),以及由谁来完成I/O读写(应用程序还是内核)1、Reactor模式(同步I/O模型通常用于实现Reactor模式)它要求主线程(I/O处理单元,下同)只负责监听文件描述符上是否有事件发生,有的话就立刻将该事件通知工作线程。除此之外,主线程不做任何其他实质性的工作。读写数据,接受新...原创 2019-04-24 22:43:52 · 836 阅读 · 0 评论 -
I/O模型中同步和异步的区别
1、同步:程序完全按照代码顺序执行(简单理解就是,我调用一个功能该功能没有结束前,我就一直死等结果)2、异步:程序的执行需要由系统事件来驱动,常见的系统事件包括中断、信号等(简单理解为:调用一个功能,不需要指代该功能最后执行的结果,该功能有结果后再通知我就行(回调通知)。也可以理解为:数据拷贝的时候,进程是否阻塞来作为同步和异步的区别)。...原创 2019-04-24 22:40:01 · 508 阅读 · 0 评论 -
僵尸进程概念以及处理方式
一、僵死进程的概念子进程先于父进程结束,而父进程又没有调用wait或者waitpid获取其退出信息。子进程还需要在其PCB中保存其退出的相关信息,所以,子进程的执行主体已经结束,但是操作系统并没有释放该进程PCB结构,以满足父进程后续对该子进程退出信息的查询(如果父进程还在运行)。在子进程结束运行之后,父进程读取其退出状态之前,我们称该子进程为僵尸进程二、处理方式...原创 2019-04-27 16:31:59 · 762 阅读 · 0 评论 -
高级I/O函数——pipe、dup、dup2、sendfile、mmap、munmap、splice、fcntl
一、创建文件描述符的函数1、pipe函数(创建管道)(1)pipe函数的定义:#include<unistd.h>int pipe(int fd[2]); 通过pipe函数创建的这两个文件描述符fd[0],fd[1]分别构成管道的两端,并且fd[1]只能用于往管道中写数据,fd[0]只能从管道中读取数据,不能反过来使用。默认情况下,这一对文...原创 2019-04-27 16:54:42 · 436 阅读 · 0 评论 -
两种高效的并发模式——半同步/半异步、领导者/追随者模式
一、并发模式中的同步和异步的区别1、同步:程序完全按照代码顺序执行(简单理解就是,我调用一个功能该功能没有结束前,我就一直死等结果)2、异步:程序的执行需要由系统事件来驱动,常见的系统事件包括中断、信号等(简单理解为:调用一个功能,不需要指代该功能最后执行的结果,该功能有结果后再通知我就行(回调通知)。也可以理解为:数据拷贝的时候,进程是否阻塞来作为同步和异步的区别)。常见的系统事件包括中...原创 2019-04-26 15:45:30 · 377 阅读 · 0 评论 -
slab分配器
slab分配器扮演了通用数据结构缓存层的角色slab层的设计有如下几个基本原则(1)频繁使用的数据结构也会频繁分配和释放,因此应当缓存他们(2)频繁分配和回收必然导致内存碎片(难以找到大块连续的可用内存)。为了避免这种现象,空闲链表的缓存会连续地存放,因为已释放的数据结构又会放回空闲链表(3)回收的对象可以立即投入下一次分配,因此,对于频繁的分配和释放,空闲链表能够提高其性能(...原创 2019-05-10 14:20:57 · 240 阅读 · 0 评论 -
系统调用号
在Linux中,每个系统调用被赋予一个系统调用号。这样,通过独一无二的号就可以关联系统调用。当用户空间的进程执行一个系统调用的时候,这个系统调用号就用来指明到底是要执行哪个系统调用;进程不会提及系统调用的名称。 系统调用号相当重要,一旦分配就不能再又任何变更,否则编译好的应用程序就会崩溃。此外,如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用,否则,以前编译过的代码...原创 2019-05-07 21:51:28 · 2263 阅读 · 0 评论 -
malloc、kmalloc、vmalloc函数的区别
malloc()返回的页在进程的虚拟地址空间内是连续的,但在物理地址空间内不一定连续kmalloc()确保分配的内存区域在物理空间上是连续的(自然在虚拟地址空间上也是连续的)vmalloc()只确保分配的页(内存区域)在虚拟地址空间内是连续的。它通过分配非连续的物理内存块,再“修正”页表,把内存映射到逻辑地址空间连续的区域中...原创 2019-05-10 16:40:27 · 553 阅读 · 0 评论 -
大端小端问题总结及相关面试题
参考https://blog.csdn.net/lishitao_578/article/details/72956312原创 2019-05-11 12:35:09 · 592 阅读 · 0 评论 -
Linux环境下段错误产生原因及调试方法
一、段错误是什么? 段错误指访问的内存超出了系统给这个程序设定的内存空间,例如访问了不存在的内存地址,访问了系统保护的内存地址,访问了只读的内存地址等二、一一举例说明访问不存在的内存地址#include<stdio.h>void mian(){ int *ptr = NULL; *ptr = 0;}访问系统受保护的内存地址#inclu...原创 2019-05-11 09:19:06 · 234 阅读 · 0 评论 -
Shell程序设计
一、为什么要使用shell编程呢?(1)是可以快速、简单地完成编程(2)如果你有一个简单的构想则可以通过它来检查自己的想法是否可行(3)shell非常适合于编写一些执行相对简单的任务的小工具,因为它们更强调的是易于配置、易于维护和可移植性,而不是看重执行效率(4)可以使用shell对进程控制进行组织,使命令按照预定顺序在前一阶段命令成功的前提下顺序执行缺陷:shell不适合用来...原创 2019-05-11 09:19:02 · 860 阅读 · 0 评论 -
Linux下共享内存的应用场景以及三种共享内存的方式
一、应用场景1、进程间通讯——生产者消费者模式 一个现场负责产生数据,一个现场负责处理数据,那么我们可以用主线程作为生产者,从键盘获取数据写入共享缓冲区,另一个线程作为消费者,从共享缓冲区读取数据,并打印。当然,这里要解决互斥的问题2、父子进程间通讯 由fork()产生的子进程和父进程不共享内存区,所以父子进程间的通讯也可以共享内存,以POSAX共享内存为例:父进程启动后使用...原创 2019-05-11 09:17:17 · 3633 阅读 · 0 评论 -
有关多线程中fork()的问题
问题1:如果一个多线程程序的某个线程调用了fork函数,那么新创建的子进程是否将自动创建和父进程相同数量的线程呢?答案:否。子进程只拥有一个执行线程,它是调用fork的那个线程的完整复制。并且子进程将自动继承父进程中互斥锁(条件变量与之类似)的状态。也就是说,父进程中已经被加锁的互斥锁在子进程中也是被锁住的问题二:子进程可能不清楚从父进程继承而来的互斥锁的具体状态(是加锁还是解...原创 2019-05-10 16:56:19 · 2376 阅读 · 0 评论 -
线程和信号
1、进程中的所有线程共享该进程的信号,所以线程库将根据线程掩码决定把信号发送给那个具体的线程。因此,如果我们在每个子线程中都单都设置信号掩码,就很容易导致逻辑错误。此外,所有线程共享信号处理函数。也就是说,当我们在一个线程中设置了某个信号的信号处理函数后,它将覆盖其他线程为同一个信号设置的处理函数。这两点都说明,我们应该定义一个专门的线程来处理所有的信号2、如果父进程希望和子进程共享地址空间,...原创 2019-05-10 16:52:21 · 531 阅读 · 0 评论 -
原子操作以及加锁机制
一、原子操作不可被中断的一个或一系列操作。二、处理器如何实现原子操作 32位处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作(1)总线锁:使用处理器提供一个LOCK#信号,当一个处理器在总线上输出此信号的时候,其他处理器的请求将被阻塞,那么该处理器可以独占使用共享内存。举例:i=7,i++;两个线程对i++进行操作,那我们最终期望的结果是9,但最终的结果...原创 2019-05-10 16:49:56 · 2901 阅读 · 0 评论 -
信号量以及信号量和自旋锁的区别
Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个不可用(已经被占用)的信号量时,信号量会将其推进一个等待队列,然后让其睡眠。这时处理器能重获自由,从而去执行其他代码。当持有的信号量可用(被释放)后,处于等待队列中的那个任务将被唤醒,并获得该信号量信号量和自旋锁的区别:(1)信号量不会禁止内核抢占,持有信号量的代码可以抢占,而自旋锁不可以。这意味着信号量不会对调度的等待时...原创 2019-05-10 16:48:12 · 2824 阅读 · 0 评论 -
自旋锁
自旋锁最多只能被一个可执行线程持有。如果一个执行线程试图获得一个被已经持有(即争用)的自旋锁,那么该线程就会一直进行忙循环—旋转—等待锁重新可用。要是锁未被争用,请求锁的指向线程便能立刻得到它,继续执行。在任意时间,自旋锁都可以防止多于一个的执行线程同时进入临界区。同一个锁可以用在多个位置,例如,对于给定数据的所有访问都可以得到保护和同步举例:门和锁:自旋锁相当于是钥匙,如果你到门口,...原创 2019-05-10 16:47:22 · 205 阅读 · 0 评论 -
进程间通信
一、Linux下进程间通信方式有哪些方式?(IPC表示进程间通信)信号、管道(有名、无名)、信号量、消息队列、共享内存、socket1、信号(1)信号是系统预先定义好的一些特定的事件,信号可以被产生,也可以被接收,产生和接收的主题都是进程。接收到信号的进程会采取相应的一些行动。一般信号是由于某些错误条件而产生的,比如内存段冲突、浮点处理器错误或非法指令等。信号也可以作为进程间传递消息...原创 2019-04-27 16:38:40 · 228 阅读 · 0 评论 -
I/O复用、select、poll、epoll的区别以及epoll的内核实现
一、select系统调用(1)select系统调用的用途是:在一段指定的时间内,监听用户感兴趣的文件描述符上的可读、可写和异常事件。(2)select的实现select的参数类型fd_set没有将文件描述符和事件绑定,它仅仅是一个文件描述符集合,因此select需要提供3个这种类型的参数来分别传入和输出可读、可写及异常等事件。这一方面使得select不能处理更多类型事件,另一方面由于内...原创 2019-04-27 16:36:14 · 178 阅读 · 0 评论 -
高性能I/O框架库Libevent
一、I/O框架库概述:I/O框架库以库函数的形式,封装了较为底层的系统调用,给应程序提供了一组更便于使用的接口,这些库函数往往比程序员自己实现的同样功能的函数 更合理、更高效、更健壮,因为它们经受住了真实网络环境下的高压测试,以及时间的考验。下面我们以Reactor模式实现,基于Reactor模式的I/O框架库包含以下几个组件:句柄(描述符)、时间多路分发器、1、句柄 I/O框架要...原创 2018-10-31 14:26:55 · 308 阅读 · 0 评论 -
I/O复用
1、在之前学的TCP连接的时候我们知道,服务器端会阻塞在两个地方,第一阻塞在连接套接口的地方(recv那行代码)当和客户端连接好之后客户端没有发送数据,那我们就会一直阻塞在那里,第二就是监听套接口的地方(accept那行代码),因为刚才的recv还没有收到客户端的数据,recv一直处于阻塞的状态,进而第一次的c也不能释放,所以造成了accept没空去处理后面来的连接,但是后来我们采用了线程和进...原创 2018-10-24 09:35:23 · 151 阅读 · 0 评论 -
服务器与一个客户端的多次连接连接
这次是一个服务器与一个客户端可以多次连接,与上次有所不同的是让客户端可以持续发送数据与服务器端连接,不仅仅是之连接一次,下面我们直接给出代码,然后分析结果//服务器端#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<as...原创 2018-10-10 15:06:06 · 3954 阅读 · 1 评论 -
套接字的连接(服务器与客户端一对一的连接)
套接字:是一种通信机制,通过这种机制,客户/服务器系统的开发工作既可以在本机可以络进行。 注:套接字的创建和使用与管道是有区别的,套接明确的将客户和服务器区分开来,套接字可以实现将多个客户连接到一个服。 套接字的连接:你可以把套接字连接想象为一客人找餐馆。顾客提前给美食指南客服打电话,客服接听电话,它转到符合客户要求的一些餐馆(...原创 2018-10-09 23:22:18 · 8473 阅读 · 1 评论 -
TCP连接的建立和关闭
TCP通过三次握手建立连接,通过四次挥手挥手关闭连接1、三次握手 第一个TCP报文段包含SYN标志,因此它是一个同步报文段,即ernest -lapyop(客户端)向Kongming20(服务器)发起连接请求,同时,该同步报文段包含一个ISN值为535734930的序号。第2个TCP发送一个同步报文段,...原创 2018-10-14 18:21:35 · 394 阅读 · 0 评论 -
TCP头部结构
TCP头部信息出现再每个TCP报文段中,用于指定通信的 源端端口,目的端口,管理TCP连接等。1、TCP固定头部结构 16位端口号:告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。请注意:进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名服...原创 2018-10-14 17:37:30 · 1616 阅读 · 0 评论 -
TCP协议的特点
一、TCP相对于UDP协议的特点是:面向连接的、字节流和可靠传输。1.1面向连接的:使用TCP协议通信的双方必须先建立连接,然后才能开始数据的读写,TCP连接是全双工的,即双方的数据读写可以通过一个连接进行。完成数据交换之后,通信双方都必须断开连接以释放资源。TCP协议的这种连接是一对一的,所以基于广播和多播(目标是多个主机地址)的应用程序不能使用TCP服。而无连接协议UDP则非常适合于广播和...原创 2018-10-14 15:29:54 · 26230 阅读 · 0 评论 -
消息队列
消息队列:消息队列提供了一种在两个不相关的进程之家传递数据的简单且有效的方法,与命名管道相比,消息队列的优势在于,它独立于发送和接收进程。它提供了一种从一个进程向另一个进程发送一个数据块(结构体)的方法。(每个数据块都有一个最大长度的限制,系统中所有队列所包含的全部数据块的总长度也有一个上限) 读消息的时候消息类型“0”代表不区分消息类型,什么类型的消息都会被读出。 消息是先存在消...原创 2018-09-23 16:53:32 · 216 阅读 · 0 评论 -
Linux基本操作命令(2)
一、vi编辑器的使用:命令模式 ——>编辑模式 输入 i/a/o/I/A/O 编辑模式 ——>命令模式 输入Esc 命令模式 ——> 末行模式 输入“:”/“ /”/“?”在末行模式下输入以下命令退出: “:w” 保存文档不退出 “wq” 保存并退出 ...原创 2018-04-27 19:01:18 · 181 阅读 · 0 评论 -
Libevent库的安装步骤
1、把压缩包拖进虚拟机2、解压 tar zxf libevent -2.0.19 -stable.tar.gz (不用手动输入这么长,你可以输入lib然后Tab键,它会自己出来)3、进入这个文件夹 cd libevent -2.0.19 -stable(也不用手动输入这么长)4、执行configure ./configure --prefix=/usr5、过滤找到Makefil...原创 2018-10-31 14:46:08 · 889 阅读 · 0 评论 -
poll系统调用
poll系统调用1、poll系统调用和select类似,也是指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者,poll函数的原型如下:#include<poll.h>int poll(struct pollfd* fds, nfds_t nfds, int timeout);timeout参数指定poll的超时值,单位是毫秒。当timeout为-1时,poll...原创 2018-10-24 15:54:36 · 1189 阅读 · 0 评论 -
epoll模型
二、epoll系统调用:1、为什么会有epoll? select和poll系统调用当有事件发生之后返回给我们但是它们俩返回的是发生事件的个数,我们并不知道具体是哪一个描述符发生了什么事,必须去一个轮询,那么当描述符的数量较多的时候,效率很明显就会降低,而epoll函数是使用一组函数来完成任务,而不是单个函数,其次,epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中,从...原创 2018-10-27 15:09:29 · 181 阅读 · 0 评论 -
fork源码剖析
fork是复制进程,那么首先要清楚进程是什么?进程是一个正在运行的程序,是资源分配的最小单位,系统管理进程是依靠对进程控制块(PCB)的管理完成的,每个进程的产生分两步,一是:分配PCB,二是准备进程实体,如分配内存空间等。fork() 创建进程,1、fork()调用一次,返回2次,子进程的返回值是0,父进程的返回值是新子进程的进程ID。 2、文件共享 在fork之前父进程打开的文件子进...原创 2019-03-30 18:21:07 · 156 阅读 · 0 评论 -
系统调用
一、用open()举例说明 在main函数中,使用open()函数,我们知道这个函数是系统调用,所以在main函数调用该函数的时候,会产生一个从用户空间到内核空间的转换,而此时的系统调用就是用户到内核的一个桥梁 内核向用户提供系统调用,会给每个系统调用一个编号,这个编号就是系统调用号(在用户空间),以后都不会改变。系统调用表(在内核空间):内核中会把系统调用的入口地址存...原创 2019-01-03 10:00:49 · 506 阅读 · 0 评论 -
底层文件的访问
一、write系统调用头文件:<unistd.h>size_t write(int fd, const void*buff, size_t nbytes);系统调用write的作用是:把缓冲区buff的前nbytes个字节写入与文件描述符fd关联的文件中,它返回实际写入的字节数。如果文件描述符有错或者底层的设备驱动程序对数据块长度比较敏感,该返回值可能会小于nbytes。如...原创 2018-11-13 09:39:43 · 969 阅读 · 0 评论 -
管道和重定向相关的命令
一、重定向输出注:以下的$都表示在普通用户的权限下就可以执行1、$ ls -1 > lsoutput.txt 这条命令把ls命令的输出保存到文件isoutput.txt中,它通过>操作符把标准输出定向到一个文件,在默认的情况下,如果该文件已经存在,他的内容将被覆盖。如果想改变默认行为,可以使用set -o noclobber(或set -C)命令设置noclobber选项,从...原创 2018-11-05 18:39:27 · 252 阅读 · 0 评论 -
libevent库的外部和内部实现
一、从大的方面来讲libevent的实现就是:1、往libevent库里注册事件(I/O事件、signal事件、定时器事件)2、启动事件循环3、通过I/O复用(select/poll/epoll)来将有就绪事件通知给系统4、根据相应事件调用相应的函数二、从细节方面来讲它就是(内部实现):1、首先应用程序准备并初始化event,设置好事件类型和回调函数;2、向libeve...原创 2018-11-05 15:55:32 · 320 阅读 · 0 评论