![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux
文章平均质量分 91
芒果再努力
逐梦需要勇气和毅力
展开
-
【Linux】线程池
2)这五个线程在处理时会呈现出一定的顺序性(观察打印的时候的线程PID),因为主线程是每秒Push一个任务,这五个线程只会有一个线程获取到该任务,其他线程都会在等待队列中进行等待,当该线程处理完任务后就会因为任务队列为空而排到等待队列的最后,当主线程再次Push一个任务后会唤醒等待队列首部的一个线程,这个线程处理完任务后又会排到等待队列的最后,因此这五个线程在处理任务时会呈现出一定的顺序性。对于长时间的任务,比如Telnet连接请求,线程池的优点就不明显了.因为Telnet会话时间比线程的创建时间大多了。原创 2023-06-05 14:16:57 · 659 阅读 · 0 评论 -
【Linux】基于阻塞队列的生产消费模型
由于生产者生产的很快,运行代码后一瞬间生产者就将阻塞队列打满了,此时生产者想要再进行生产就只能在full条件变量下进行等待,直到消费者消费完一个数据后,生产者才会被唤醒进而继续进行生产,生产者生产完一个数据后又会进行等待,因此后续生产者和消费者的步调又变成一致的了。虽然消费者消费的很快,但一开始阻塞队列中是没有数据的,因此消费者只能在empty条件变量下进行等待,直到生产者生产完一个数据后,消费者才会被唤醒进而进行消费,消费者消费完这一个数据后又会进行等待,因此生产者和消费者的步调就是一致的。原创 2023-06-03 15:13:13 · 464 阅读 · 2 评论 -
【Linux】基于环形队列的生产者消费者模型
上述代码,我们分开的使用两把锁,就维护了生产者和生产者的互斥关系,消费者和消费者的互斥关系,他们两套互斥互不影响,任意时刻最多只允许有一个生产者执行流进入生产,最多只允许有一个消费者执行流进入消费,每一个能进去的人,前提是申请信号量成功,他们进入临界资源的生产和消费的同步和互斥由信号量保证。信号量的P操作本身就是原子的,如果放在前面,那么就只有申请锁成功的人才能申请信号量,即使信号量设置的非常高,但实际上申请的时候还是要一个一个的申请, 不是我们想要的效果,放在前面和单生产者单消费者没有本质差别。原创 2023-06-01 14:48:07 · 471 阅读 · 0 评论 -
【Linux】信号量
信号量本质是一个计数器,如果将信号量的初始值设置为1,那么此时该信号量叫做二元信号量,信号量的初始值为1,说明信号量所描述的临界资源只有一份,此时信号量的作用基本等价于互斥锁。1)多个执行流为了访问临界资源会竞争式的申请信号量,因此信号量是会被多个执行流同时访问的,也就是说信号量本质也是临界资源。当执行流在申请信号量时,可能此时信号量的值为0,也就是说信号量描述的临界资源已经全部被申请了,此时该执行流就应该。信号量的本质是计数器,但不意味着只有计数器,信号量还包括一个等待队列。原创 2023-05-29 19:54:36 · 1072 阅读 · 0 评论 -
【Linux】可重入VS线程安全
线程安全讨论的是线程执行代码时是否安全,重入讨论的是函数被重入进入。原创 2023-05-27 23:34:02 · 823 阅读 · 0 评论 -
【Linux】死锁
3)直到使用锁的进程已经使用完毕,也就是锁的资源已经就绪,此时就会从锁的资源等待队列中唤醒一个进程,将该进程的状态由S状态改为R状态,并将其重新链接到运行等待队列,等到CPU再次调度该进程时,该进程就可以使用到锁的资源了。在运行等待队列中的进程本质上就是在等待CPU资源,实际上不止是等待CPU资源如此,等待其他资源也是如此,比如锁的资源、磁盘的资源、网卡的资源等等,它们都有各自对应的资源等待队列。情形:当某一个进程在被CPU调度时,该进程需要用到锁的资源,但是此时锁的资源正在被其他进程使用。原创 2023-05-26 23:55:35 · 692 阅读 · 0 评论 -
【Linux】线程同步
1)条件等待是线程间同步的一种手段,如果只有一个线程,条件不满足,一直等下去都不会满足,所以必须要有一个线程通过某些操作,改变共享变量,使原先不满足的条件变得满足,并且友好的通知等待在条件变量上的线程。3)当线程进入临界区时需要先加锁,然后判断内部资源的情况,若不满足当前线程的执行条件,则需要在该条件变量下进行等待,但此时该线程是拿着锁被挂起的,也就意味着这个锁再也不会被释放了,此时就会发生死锁问题。函数时,还需要将对应的互斥锁传入,此时当线程因为某些条件不满足需要在该条件变量下进行等待时,就会。原创 2023-05-25 09:40:18 · 633 阅读 · 0 评论 -
【Linux】线程互斥
回忆例子: 临界资源和临界区进程之间如果要进行通信我们需要先创建第三方资源,让不同的进程看到同一份资源,这份第三方资源可以由操作系统中的不同模块提供,所以进程间通信的方式有很多种进程间通信中的第三方资源就叫做临界资源,访问第三方资源的代码就叫做临界区因为多线程的大部分资源都是共享的,线程之间进行通信不需要费那么大的劲去创建第三方资源此时我们相当于实现了主线程和新线程之间的通信,其中,因为它被多个执行流共享。原创 2023-05-23 21:26:51 · 943 阅读 · 0 评论 -
【Linux】IO多路转接-poll
最初poll的数组中只有监听套接字, 当我们用telnet工具连接poll服务器后,poll服务器调用的poll函数在检测到监听套接字的读事件就绪后就会调用accept获取建立好的连接,然后将新获取到的套接字添加到数组中,并关心其读事件是否就绪, 当数据就绪了,就会通知我们,此时客户端发来的数据也能够成功被poll服务器收到并进行打印输出。注意:此时不能直接读取,因为有新链接到来,不代表有数据就绪,不代表能读取,如果此时没有数据,但是我们进行了读取,那么进程就会阻塞在那里进行等待,那么什么时候数据到来呢?原创 2023-05-15 14:43:28 · 519 阅读 · 0 评论 -
【Linux】IO多路转接 - epoll
命令,查看当前epoll服务器的文件描述符的使用情况,其中文件描述符0、1、2是默认打开的,分别对应的是标准输入、标准输出和标准错误,3号文件描述符对应的是监听套接字,4号文件描述符对应的是服务器创建的epoll模型,5号和6号文件描述符对应的分别是正在访问服务器的两个客户端。2)所谓的事件处理并不是调用epoll_wait将底层就绪队列中的就绪事件拷贝到用户层,比如当这里的读事件就绪后,我们应该调用accept获取底层建立好的连接,或调用recv读取客户端发来的数据,这才算是将事件处理了。原创 2023-05-15 14:43:15 · 624 阅读 · 0 评论 -
【Linux】IO多路转接-select
1)之前我们说fd_set的时候就验证过:其实select可监控的文件描述符个数就是1024个, 因此我们实现的select服务器当中将fd_array数组的大小设置为1024是足够的,因为readfds当中最多就只能添加1024个文件描述符,但不同环境下fd_set的大小可能是不同的,并且fd_set的大小也是可以调整的(涉及重新编译内核),因此之前select服务器当中对NUM的宏定义正确写法应该是这样的。原创 2023-05-12 10:17:07 · 464 阅读 · 0 评论 -
【Linux】认识高级IO & 5种IO模型
内存和外设进行沟通的动作叫做IO, IO也就是:输入和输出在冯诺依曼体系当中:将数据从输入设备拷贝到内存就叫做输入,将数据从内存拷贝到输出设备就叫做输出对文件进行的读写操作本质就是一种IO,文件IO对应的外设就是磁盘对网络进行的读写操作本质也是一种IO,网络IO对应的外设就是网卡在网络层面,数据往网络里写的本质是将数据从内存拷贝到网卡上,从网络里读的本质是将数据从网卡拷贝到内存中,回顾之前学到的所有关于IO的接口都可以称作拷贝接口,以send为例子。原创 2023-05-12 10:17:36 · 491 阅读 · 0 评论 -
【项目】基于负载均衡式-在线OJ系统
【项目】基于负载均衡式-在线OJ系统原创 2023-05-03 23:35:38 · 613 阅读 · 0 评论 -
【Linux】线程概念
在一个程序里的一个执行路线就叫做线程(thread), 更准确的定义是:线程是“一个进程内部的控制序列”一切进程至少都有一个执行线程线程在进程内部运行,本质是在进程地址空间内运行在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更轻量化透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。原创 2023-04-06 19:42:42 · 303 阅读 · 0 评论 -
关于volatile关键字-结合信号理解
此时就算我们编译代码时携带 -O3 选项,当进程收到2号信号将内存中的flag变量置1时,main函数执行流也能够检测到内存中flag变量的变化,进而跳出死循环正常退出。而while循环是在main函数当中的,编译器发现:我们只对flag这个变量做检测,而不做修改, 编译器直接优化,把flag的值保存在寄存器中,直接在CPU检测。此时main函数在检测flag时只检测寄存器里面的值,而handler执行流只是将内存中flag的值置为1了,那么此时就算进程收到2号信号也不会跳出死循环。原创 2023-04-03 12:33:26 · 238 阅读 · 1 评论 -
【Linux】信号的捕捉
其中:该图形与直线有几个交点就代表在这期间有几次状态切换,箭头的方向就代表着此次状态切换的方向,图形中间的圆点就代表着检查pending表问:为什么识别到信号的处理动作是自定义时,不能直接在内核态执行用户空间的代码理论上来说是可以的,因为内核态是一种权限非常高的状态,但是不能这样设计,原创 2023-04-03 12:30:43 · 598 阅读 · 0 评论 -
【Linux】可重入函数
1.main函数中调用插入函数,将节点node1插入到链表中,但这里的插入有两步,现在做完了第一步:p->next = head ,因为突发情况,硬件中断使进程切换到内核,再次回到用户态之前,检查到有信号待处理,于是进入到用户态处理handle函数。最终一套流程下来 ,我们可以发现:main函数和sighandler函数先后向链表中插入了两个结点,但最后只有node1结点真正插入到了链表中,而。4.再次回到用户态就从main函数调用的insert函数中继续往下执行,即继续进行结点node1的插入操作。原创 2023-03-31 23:43:44 · 251 阅读 · 1 评论 -
【Linux】内核态&&用户态
内核级页表是一个全局的页表,它用来维护操作系统的代码与进程之间的关系,因此,在每个进程的进程地址空间中,用户空间是属于当前进程的,每个进程看到的代码和数据是完全不同的,但内核空间所存放的都是操作系统的代码和数据,所有进程看到的都是一样的内容。其中,由用户态切换为内核态我们称之为陷入内核,每当我们需要陷入内核的时,本质上是因为我们需要执行操作系统的代码,比如系统调用函数是由操作系统实现的,我们要进行系统调用就必须先由用户态切换为内核态。1.在当前进程的进程地址空间中的内核空间,找到操作系统的代码和数据。原创 2023-03-31 23:43:06 · 467 阅读 · 0 评论 -
【Linux】SIGCHLD信号
这样的写法能够满足各种子进程退出的情况,假设创建10个子进程, 它们同时退出了,每个子进程退出都向父进程发送信号, 但是pending位图只能有一个比特位记录这个SIGCHILD信号, 如果只wait一次,那么只能读取一个子进程,剩下的9个就没被读到,所以设置while循环, 不等待指定一个子进程->所以参数设定-1循环式的把所有子进程退出都读取到。,父进程可以自定义SIGCHLD信号的处理动作,这样父进程就只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程。原创 2023-03-24 08:30:25 · 492 阅读 · 0 评论 -
【Linux】产生信号的方式
C/C++程序会崩溃,是因为程序当中出现的各种错误最终一定会在硬件层面上有所表现,进而会被操作系统识别到,然后操作系统就会发送相应的信号将当前的进程终止。原创 2023-03-19 23:44:26 · 565 阅读 · 0 评论 -
【Linux】信号常见概念
1)默认动作:执行信号的默认注册行为, 如:9号信号:SIGKILL 杀死自身进程2)忽略动作:忽略掉该信号,不做出任何反应 这也是一种信号处理的方式3)自定义捕捉:如:signal函数,对信号进行捕捉,执行用户注册的行为,即调用修改后的 handler 方法提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号可以查看各个信号默认的处理动作。原创 2023-03-17 17:54:06 · 742 阅读 · 1 评论 -
【Linux】命名管道&命名管道和匿名管道的对比&命令行中的管道
注意:实现服务端(server)和客户端(client)之间的通信之前,我们需要先让服务端运行起来,让服务端运行后创建一个命名管道文件,然后再以读的方式打开该命名管道文件,之后服务端就可以从该命名管道当中读取客户端发来的通信信息了。对于如何让客户端和服务端使用同一个命名管道文件,这里我们可以让客户端和服务端包含同一个头文件,该头文件当中提供这个共用的命名管道文件的文件名,这样客户端和服务端就可以通过这个文件名,打开同一个命名管道文件,进而进行通信了。原创 2023-03-12 23:10:59 · 479 阅读 · 0 评论 -
【Linux】信号量&system V IPC之间的联系
这样设计的好处就是:在操作系统内可以定义一个struct ipc_perm类型的数组,此时每当我们申请一个IPC资源,就在该数组当中开辟一个这样的空间,因为进程间通信需要引入能被多个进程看到的资源,但这也同时带来了临界资源的数据不安全的问题,信号量是用来保护临界资源的,前提是每个人得先看到信号量,因此。1)能被多个执行流同时访问的资源都是临界资源,比如,显示器文件、进程间通信的时候:管道、共享内存、消息队列都是临界资源。,所以所有的Syetem V表中的IPC资源的结构体的第一个成员都是。原创 2023-03-12 23:12:30 · 81 阅读 · 0 评论 -
【Linux】进程间通信-共享内存
为了让服务端和客户端在使用ftok函数获取key值时,能够得到同一种key值, 那么服务端和客户端传入ftok函数的路径名和和整数标识符必须相同,这样才能生成同一种key值,进而找到同一个共享资源进行挂接,这里我们可以将这些需要共用的信息放入一个头文件当中。,而这里shmget函数的返回值实际上就是共享内存的句柄,这个句柄可以在用户层标识共享内存当共享内存被创建后,我们在后续使用共享内存的相关接口时,都是需要通过这个句柄对指定共享内存进行各种操作。原创 2023-03-08 09:16:18 · 407 阅读 · 0 评论 -
【Linux】进程间通信概念&匿名管道
进程间通信简称IPC(Interprocess communication):进程间通信就是在不同进程之间传播或交换信息为什么要有进程通信?因为进程具有独立性,一个进程看不到另一个进程的资源和信息, 那么它们直接交互数据成本很高!操作系统需要设计特定的通信方式来解决这个问题!写端不写或写得慢的情况下 ,读端进程一直读: 此时会因为管道里面没有数据可读,对应的读端进程会被挂起,直到管道里面有数据后,读端进程才会被唤醒。原创 2023-03-08 09:15:53 · 240 阅读 · 0 评论 -
【Linux】软硬链接
软链接文件的inode号与源文件的inode号是不同的 ,软链接文件相对于源文件来说是一个独立的文件,该文件有自己的inode号,但是该文件只包含了源文件的路径名,所以软链接文件的大小要比源文件小得多。我们可以发现,软链接由自己独立的inode 即: 软链接是一个独立的文件,他有自己的inode,也有自己的数据块block,数据块中保存的是它所指向的文件的路径+文件名。与软连接不同的是,当硬链接的源文件被删除后,硬链接文件仍能正常执行,只是文件的链接数减少了一个,因为此时该文件的文件名少了一个。原创 2023-03-05 19:31:20 · 858 阅读 · 0 评论 -
【Linux】动静态库-概念&制作
1.制作库的本质: 将所有的.o文件打包静态库:ar -rc2.发布库:将 所有的.h文件 *.h 和 .a /.so发布出去3.使用:拿到别人的库和头文件,加入到自己的项目中静态库可以直接使用,动态库还要告知系统动态库的路径, 如果你提供的是一个静态库,那我们只能将这个库静态链接到程序中;,如果你提供的是一个动态库,那我们只能将这个库动态链接到程序中如果既想动态链接,又想静态链接,一般要提供两个版本的库文件问:gcc默认是怎么链接gcc优先是动态链接 并且是release版本!原创 2023-03-01 18:41:56 · 447 阅读 · 0 评论 -
【Linux】文件时间-ACM
实际操作中,文件的Access时间可能没有变化,这是因为在新的Linux内核中,Access时间不会被立即更新,而是经过一定的时间间隔,OS才会自动进行更新, 因为查看文件和读取文件是比较频繁的事情,如果频繁的去更新时间,就可能存在刷盘的问题,会让我们的Linux系统变得卡顿。当我们修改文件内容时,文件的大小一般也会随之改变,所以一般情况下Modify的改变会带动Change一起改变,但修改文件属性一般不会影响到文件内容,所以一般情况下Change的改变不会带动Modify的改变。原创 2023-03-01 18:43:08 · 351 阅读 · 0 评论 -
【Linux】理解文件系统
因为拷贝文件需要先创建文件,然后再对该文件进行写入操作,该过程需要先申请inode号并填入文件的属性信息,之后还需要再申请数据块号,最后才能进行文件内容的数据拷贝,而删除文件只需将对应文件的inode号和数据块号置为无效即可,无需真正的删除文件,因此拷贝文件是很慢的,而删除文件是很快的。要创建文件,就要在inode Table中申请一个未被使用的inode,填入文件的属性, 在Data blocks中也要创建一个block,用于存放文件的内容, inode用数组存储了相关联的blocks块编号,原创 2023-03-01 18:41:22 · 2009 阅读 · 0 评论 -
【Linux】重定向原理&&dup2&&缓冲区
此时我们的数据还在用户级缓冲区, 因为把文件描述符关闭了,所以没有地方去刷新,因此什么也没有看到。原创 2023-02-25 16:31:28 · 3721 阅读 · 1 评论 -
【Linux】系统文件IO-open&&close&&read&&write&&文件描述符
Linux中做了软件的虚拟层vfs(虚拟文件系统),会统一维护每一个文件的结构体struct file,这个结构体包含了一批函数指针,这批函数指针帮我们直接去指向底层方法,在上层我们看待文件就可以以统一的struct_file的方式去看待,所以一切皆文件指的是vfs层面上看待它,而不是在驱动层。所有的文件操作,表现上都是进程执行对应的函数,即进程对文件的操作,要操作文件必须要先打开文件,要打开文件,就得先将文件相关的属性信息加载到内存,操作系统中存在大量的进程,, 那0,1,2这三个值代表什么?原创 2023-02-23 08:57:11 · 5875 阅读 · 1 评论 -
【Linux】基础IO-回顾C语言文件操作
上述所写程序中,当我们用fopen以写入的方式打开文件,如果该文件不存在,系统会默认在当前目录下为我们创建该文件,那我们所说的当前路径是什么呢?首先我们准备一个程序验证一下:例如:我们在FileCode目录下运行可执行程序myfile, 那么可执行程序所创建的文件就出现在FileCode目录下那这样可以说明:当前路径指的是当前可执行程序所处的路径吗?并不能!!!此时我们把当前FileCode目录下的log.txt文件删除, 然后我们cd ..回退到上级目录,然后执行可执行程序myfile,会发生什么呢。原创 2023-02-21 09:37:21 · 6117 阅读 · 1 评论 -
【Linux】进程替换
所以的接口,看起来没有太大的差别,只有一个就是参数的不同,为什么会有这么多接口?是为了满足不同的应用场景。原创 2023-02-19 18:43:22 · 5641 阅读 · 0 评论 -
【Linux】进程终止&&进程等待
阻塞的时候,没有跑父进程的代码,父进程如果是在阻塞状态去等子进程,父进程就是处于等待状态,并不会被CPU运行,让父进程等待实际是把父进程的PCB加入到等待队列当中,将父进程的状态从R状态变为S状态,当操作系统识别到子进程执行结束时,发现父进程在等待队列当中, 把父进程的PCB重新加入到运行队列中,然后执行后序的过程,获取子进程的退出结果。而对于父进程来说,子进程是需要被标识的,因为父进程创建子进程的目的是让其执行任务的,父进程只有知道了子进程的PID才能很好的对该子进程指派任务。可以查看子进程的退出码。原创 2023-02-17 12:28:21 · 6355 阅读 · 0 评论 -
【Linux】程序&进程地址空间
【Linux】程序&进程地址空间原创 2023-02-14 13:20:41 · 5760 阅读 · 2 评论 -
【Linux】环境变量&本地变量
要执行一个可执行程序必须要先找到它在哪里,既然不带./就可以执行系统命令,说明系统能够通过命令的名称找到指令的位置,而系统是无法找到我们自己的可执行程序的, 带。当然我们也可也把我们的可执行程序加到PATH路径里面,那么我们执行可执行程序,就可以直接使用可执行程序的文件名字来直接运行。指令有很多选项,用来完成同一个命令的不同子功能,选项底层使用的就是我们的命令行参数,这也是命令行参数的意义。的字符串长度,跳过前面的内容, 来到/位置,然后要的是/后面的内容。原创 2023-02-11 09:43:04 · 5985 阅读 · 1 评论 -
【Linux】进程概念&&进程状态&&进程优先级
在系统层面,该进程曾经申请的资源并不是立即被释放,而是要暂时存储一段时间,以供操作系统或是其父进程进行读取,如果退出信息一直未被读取,则相关数据是不会被释放掉的,一个进程若是正在等待其退出信息被读取,那么我们称该进程处于僵尸状态,即:当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。我们需要演示的是: 父子进程执行一段时候后,我们让子进程退出,父进程一直执行 即:当子进程退出了,父进程还在执行,但是父进程没有读取子进程的退出信息,那么子进程就会进入僵尸状态。原创 2023-02-08 12:14:51 · 5679 阅读 · 0 评论 -
【Linux】冯诺依曼体系与操作系统(OS)概念
1)计算机的作用就是为了解决人的问题,而要解决问题,首先需要将数据或是问题输入到计算机当中,所以计算机必须要有输入设备.2)计算机解决完问题后还需要将计算结果输出显示出来,所以计算机必须要有输出设备.3)计算机通过输入设备得到数据,数据在计算机当中进行一系列的算术运算和逻辑运算后,通过输出设备进行输出,于是就得到了下述的过程:4)计算机当中只有算术运算功能和逻辑运算功能是不够的,还需要有控制功能,控制何时从输入设备获取数据,何时输出数据到输出设备等。原创 2023-02-05 21:03:21 · 9239 阅读 · 4 评论 -
【Linux】基本开发工具的使用-yum&&vim&&gcc/g++&&git
在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.软件包和软件包管理器, 就好比 “App” 和 “应用商店” 这样的关系yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器.原创 2023-02-04 14:41:51 · 6363 阅读 · 1 评论 -
【Linux】权限管理-权限的概念,umask,粘滞位
【Linux】权限管理-权限的概念,umask,粘滞位原创 2022-11-15 16:18:31 · 6035 阅读 · 1 评论