
操作系统
文章平均质量分 93
_Zebra
即使可能性很小,也要一直努力,无限接近于0的可能性永远不会是0
展开
-
使用C++11的Thread和condition_variable实现单例模式的线程池
首先我们来看一下线程池的大致结构,这里先不实现单例模式,线程池使用了模板类,可以用于任意类型的任务对象,其中有一些成员变脸,_task_queue用于保存线程池中要执行的任务,_count表示线程的数量,_isStop表示线程池是否要停止运行,停止线程执行任务,还有一个互斥锁用于保证线程对任务队列的访问时安全的,条件变量用于当任务队列为空时,让线程等待;tips:任务队列中的任务是T类型的指针,如果任务执行完就不需要的话,我们可以在这里delete释放任务对象占用的空间,当然也可以由主线程去释放。原创 2023-03-14 00:10:14 · 730 阅读 · 1 评论 -
多线程~实现一个自己的线程池,以及基于单例模式的线程池
池化技术本质上都是为了提高效率。线程池也是同理,提前准备好一些线程,用来随时处理任务(处理完任务又放回池子),就称为线程池。为了提高效率。避免了在处理短时间任务时由于创建与销毁线程影响任务处理效率如果没有线程池,比如用户向服务器发起请求的时候,服务器收到请求需要先创建线程(需要耗时),然后再给用户提供服务,这对用户来说就是不必要的时间消耗。因此,可以提前准备好一些线程,服务器收到用户请求的时候马上就可以从线程池拿出一个线程来给用户提供服务。原创 2023-01-17 12:10:30 · 1303 阅读 · 0 评论 -
多线程~POSIX信号量实现生产者消费者模型,PV操作
信号量本质就是一把计数器,描述临界资源中资源数目的大小,合理使用可以达到对临界资源进行预订的目的。(最多能有多少资源分配给线程)多线程预定资源的方法:临界资源如果可以被划分成为一个一个的小资源,如果处理得当,我们也有可能让多个线程同时访问临界资源的不同区域,从而实现并发并行的访问临界资源。原创 2023-01-13 21:48:54 · 975 阅读 · 0 评论 -
多线程-生产者消费者模型,条件变量的使用,阻塞队列的实现
因为我们在调用pthread_cond_wait的时候,一般都是占用着锁的(一般都是检测到临界资源,发现不满足条件,才会调用这个wait方法),此时如果不把锁释放,直接wait的话,那就死锁了,其他线程也无法获取锁,修改这个临界资源。当消费者Pop取走任务的时候,同理要判断队列是否为空,如果空了就让消费者等待,然后加锁对队列进行操作,最后唤醒生产者来生产队列中的任务。暂时等待,而不是一直尝试抢票,如果一直抢票,抢票线程会一直获取锁,然后判断是否有票,没票,释放锁,不停循环这个操作,做无用功,而且占用锁。原创 2023-01-05 18:45:48 · 723 阅读 · 0 评论 -
操作系统~Linux~线程的互斥,mutex互斥锁的使用及其原理
1.临界资源:凡是被线程共享访问的资源都是临界资源(多线程、多进程打印数据到显示器,显示器就是临界资源)2.临界区:代码中访问临界资源的代码(在代码中,不是所有的代码都是进行访问临界资源的。而访问临界资源的代码区域我们称之为临界区)3.对临界区进行保护的功能,本质就是对临界资源的保护。方式:互斥或者同步4.互斥:在任意时刻,只允许一个执行流访问某段代码(访问某部分资源〉,就可以称之为互斥5.同步:一般而言,让访问临界资源的过程在安全的前提下(一般都是互斥and原子的),让访问资源具有一定的顺序性(具有合理性原创 2022-12-31 16:40:00 · 2669 阅读 · 0 评论 -
操作系统~Linux~线程控制,POSIX线程库的使用
功能:创建一个新的线程原型int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);参数返回值:成功返回0;失败返回错误码pthread_self()函数可以返回当前线程的id,这是一个地址,所以我们用十六进制打印这个地址结果分析 可以看到,主线程的线程id和新线程的线程id是不同的,而且是地址,同时我们可以发现参数zebra成原创 2022-12-26 18:08:03 · 946 阅读 · 1 评论 -
Linux~操作系统~什么是线程?线程底层结构是怎样的?线程的优缺点?
把程序文件加载到内存,操作系统为该进程创建PCB,页表等管理进程的数据机构,这就形成了进程,是程序的执行实例。(一个程序可以有多个进程来执行)是在进程内部运行的一个执行分支(执行流),属于进程的一部分,粒度要比进程更加细和轻量化。进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位。原创 2022-12-21 14:24:59 · 599 阅读 · 0 评论 -
Linux操作系统~信号处理的底层原理
执行用户提供的信号处理函数handler。比如我们要处理信号4,此时我们处于内核态,根据4号信号的handler表里面找到用户定义的handler函数地址,然后切换到用户态执行信号处理函数(这里调用handler对操作系统来说相当于是一次回调)。原创 2022-12-18 15:39:17 · 772 阅读 · 0 评论 -
Linux操作系统~进程崩溃的原理是什么?信号的产生方式有哪些?
signal函数:修改进程对信号的默认处理动作signum:表示要修改几号信号handler表示要做出的处理动作函数e.g.://传入的信号表示要对几号信号进行自定义处理{//打印执行的是几号信号的处理函数,打印执行}int main(){//通过signal注册2号信号的处理动作,改成自定义处理动作while(1){sleep(1);}return 0;}原创 2022-12-09 20:01:05 · 2384 阅读 · 0 评论 -
Linux操作系统~尝试自己制作并使用动静态库
之后给别人用的时候,库文件和头文件都给,这样库文件就可以封装起来(转换成二进制文件)了。如果我们没有打包成库,.h文件(include的时候要写正确路径,或者借用环境)和.cc文件是分离的,此时编译的时候需要把.cc文件也要带上,否则会报错。为什么要这么设计呢?静态库在运行的时候不需要找库,所以运行的时候直接./mytest就行了,在编译的时候需要指定。动态库在运行的时候需要找库,所以除了在编译期间告诉编译器库在哪里,库的真实名字:去掉lib前缀,去掉.a...,so...后缀,剩下的就是库名称!原创 2022-11-22 23:53:07 · 1190 阅读 · 0 评论 -
Linux操作系统~带你理解文件系统与软硬链接
这两个是不一样的概念,C语言中的FILE内部有当前文件对应的文件描述符fd,同时还有C语言层面上的缓冲区的内容等信息。然后操作系统根据FILE里面的fd,在fd作为下标的指针数组里面找到的file对象,里面存放了文件相关的inode元的信息(文件的属性信息),和C语言的FILE是不一样的。因为IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问的。所以C库当中的FILE结构体内部,必定封装了fd。原创 2022-11-19 12:30:00 · 1313 阅读 · 0 评论 -
Linux操作系统~系统文件IO,什么是文件描述符fd?什么是vfs虚拟文件系统
我们的输入输出最终都是访问硬件,OS是操作系统的管理者我们使用的都是语言层面上的接口,所以的“语言”上的操作,都必须贯穿OS。然而操作系统不相信任何人,所以访问操作系统都是需要通过系统调用的接口的。因此几乎所有的语言fopen,fclose,fread,fwrite,fgets,fputs,fgetc,fputc等底层一定需要使用OS提供的系统调用上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。而,原创 2022-11-17 13:06:38 · 1922 阅读 · 0 评论 -
Linux操作系统~进程替换,exec系列函数的使用
这六个函数(加上execvpe一共七个)实际上只是参数上的不同,最终都是调用execve,系统给我们提供的实际上只有这一个接口,其他接口都是在此基础上封装出来的。(通过man手册也可以发现execve在man手册的2区内,表示是系统调用)原创 2022-11-15 21:10:26 · 1517 阅读 · 0 评论 -
Linux操作系统~进程fork到wait到底怎么用?
用户调用waitpid让父进程等待子进程退出并变成僵尸状态,然后从进程的pcb中获取exit_code和signal,组合起来放到status中,父进程中的status和用户层的status也就都发生了变化,用户就可以看到进程的退出码和终止信号了。2.既然父进程要拿到子进程的执行结果,也就需要保证父进程在子进程之后退出,使用wait可以保证时序问题,即让子进程先退出,父进程后退出。(查看进程的退出码)3.子进程退出的时候会先进入僵尸状态,会造成内存泄漏的问题,需要通过父进程wait,释放子进程占用的资源。原创 2022-11-11 20:01:04 · 2023 阅读 · 0 评论 -
Linux操作系统~什么是虚拟地址?深度剖析进程地址空间
1.堆是堆,栈是栈,堆栈是栈2.经过验证,C/C++的程序地址空间就是如图所示,栈区是往低地址方向增长的。子进程中对val进行修改,会发生写时拷贝。从而拷贝一份数据到另外的地方,变量的值是不一样的,但是他们两个变量对应的地址却是一样的,说明这个地址不是真正的物理地址,而是虚拟地址。原创 2022-11-07 08:45:00 · 1834 阅读 · 0 评论 -
Linux操作系统~进程有哪些状态?
D状态是一种不可中断的睡眠状态。比如一个进程让磁盘你帮我写1G数据到磁盘里面去,磁盘开始忙了,进程就会进入D状态等待磁盘写入完成(因为这种等待状态是不允许被中断的,因为如果中断进程的等待,磁盘写入数据完成后,无法向原来的进程返回错误/正确信息,会导致一些问题)D状态就是深度睡眠,处于这种状态的进程不能被中断的(不可以被杀掉)进程在内核中某些不能被信号打断,例如对某些硬件设备进行操作时刻(等待磁盘Io,等待网络io等等)。进程处于D状态一般情况下很短暂,不应该被top或者ps看到。原创 2022-11-04 19:50:56 · 5054 阅读 · 0 评论 -
Linux操作系统~什么是进程,进程的内部结构是什么?fork如何创建子进程?
一个进程里面有进程代码数据文件+PCB,PCB用双向链表的方式链接起来(组织进程),操作系统以后找进程的时候直接找PCB就行,而不是去找进程的代码和数据。子进程已经创建好了,此时父子进程都会向下执行,都会return,所以也就有两个返回值了(fork那条语句,子进程也会执行一部分,就是最后返回的那部分,所以会有两个返回值)如果fork成功了,对于父进程就会返回子进程的PID,对于子进程就会返回0。5.进程是具有独立性的,就算父进程挂了(修改数据),也不会影响子进程(不影响子进程的数据);原创 2022-11-01 14:58:33 · 470 阅读 · 0 评论