Linux--进程(2)
目录
前言
1. 进程的状态
1.1 进程排队
1.2 运行,阻塞,挂起
2.Linux下具体的进程状态
2.1僵尸和孤儿
3.进程的优先级
4.Linux的调度与切换
前言
这篇继续来学习进程的其它知识
上篇文章:Linux--进程(1)-CSDN博客
1. 进程的状态
关于进程的状态:
首先我们来轻量聊一下进程排队这件事情--队列
然后谈一谈教材上关于进程状态的表述---运行,阻塞,挂起
最后看看Linux下具体的进程状态(具体的看看什么是运行,什么是阻塞,什么是挂起)
1.1 进程排队
进程不是一直在运行的;进程放在了cpu上,也不是一直在前全运行的
进程不是在一直运行的,也可能在等待某中软硬件资源,比如我们在写c语言代码的时候,运行到scanf那一行,进程就在等待输入。
进程放在了cpu上,也不是一直在前全运行的:每个进程都会被分配一个时间段,我们称之为时间片,如果时间结束该进程还在运行,CPU将进行剥夺资源并分配给另一个进程。我们写代码的时候有时候会遇到死循环,当代码运行生成了进程,进程时间结束,我们会发现循环仍未终止,但实际上这个进程资源已经被剥夺了。在Linux系统上,他可能在5毫秒到800毫秒之间。由于时间片极短,用户不会感觉到程序的切换,从而形成了多个进程同时运行的错觉。
我们接着来谈谈排队的问题
首先进程排队一定是在等待某种资源
1.进程=task_struct+可执行程序,进程排队不是可执行程序在排队,而是task_struct对象(PCB)在排队,比如你实习投简历的时候,是简历在排队不是你人在排队。
2.PCB的问题
一个进程的PCB可以被链入多种数据结构中,在不同的场景下,操作系统可能会采用不同的数据结构来组织和管理PCB。一个PCB通常不会同时被链接到多种数据结构中。它会被放置在最适合当前管理需求的数据结构中。例如,当进程处于 就绪状态时,它的PCB会被放在就绪队列中;当进程因等待某个事件而被阻塞时,它的PCB会被移到阻塞队列中。操作系统会根据需要动态地更新和移动PCB,以确保进程能够按照正确的顺序和方式得到调度和执行。
1.2 运行,阻塞,挂起
1.所谓的状态本质就是在task_struct中的一个整型变量
eg:所谓的状态不过是status所被给予的数字
2.状态决定了什么?
状态决定了进程的后续动作,Linux中可能存在多个进程都要根据他的状态执行后续的动作。在这种情况下就需要让进程去排队了,一个CPU一个运行队列
运行状态:运行状态是进程实际占用CPU执行其程序代码的状态。我们在主流的操作系统中,只要进程处在运行队列中排队,我们都可以称这个进程在运行状态。
在前面我们说了,进程不是在一直运行的,也可能在等待某中软硬件资源,进程放在了cpu上,也不是一直在前全运行的。
在这里我以硬件为例,来了解阻塞状态。
操作系统,管理硬件,要先把硬件表述起来,再去管理,每个硬件都有属于自己的对象,cup也是硬件,他有他的运行队列,其它硬件也有其它硬件的队列,称之为等待队列。
我引用上面的例子,当代码运行到scanf的时候,进程就在等待输入,这时进程的状态就会从运行状态变为阻塞状态,进程会被操作系统(OS)搬迁到键盘的等待队列中去,当输入完成之后,OS就会知道进程已经就绪了,这时进程又会重新被搬迁到运行队列中去,此时进程变为运行状态。(状态的变迁,实际上就是OS将PCB搬迁到不同的队列中)
总结阻塞状态:当我们的进程正在等待软硬件资源的时候,资源如果没有就绪,我们的进程task_struct只能:1.将自己设置为阻塞状态 2.将自己的PCB链入等待的资源提供的等待队列中去。
挂起状态:这个状态并不常见,这个状态的前提是计算机资源已经比较吃紧了。因为这些进程暂时没有动作,此时OS就会将阻塞状态的进程(代码和数据,不包括PCB)转到外设中存(磁盘的swap分区)储起来(唤出),需要时再唤入。
2.Linux下具体的进程状态
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。
下面的状态在kernel源代码里定义:
/* * The task state array is a strange "bitmap" of * reasons to sleep. Thus "running" is zero, and * you can test for combinations of others with * simple bit tests. */ static const char * const task_state_array[] = { "R (running)", /* 0 */ "S (sleeping)", /* 1 */ "D (disk sleep)", /* 2 */ "T (stopped)", /* 4 */ "t (tracing stop)", /* 8 */ "X (dead)", /* 16 */ "Z (zombie)", /* 32 */ };
- R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠(阻塞)状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
我们举一个样例,来看看在Linux中状态具体的样子。
我们运行这个代码,查看了这个进程的状态发现它处于S(阻塞)状态,这时我们就有疑问了,这段代码进入了死循环应该是一直在运行的啊,不应该是R(运行)状态吗?
这是因为,printf的缘故,这个程序的大多数时间都在执行printf函数,这时就会发生系统调用访问外设,在这些系统调用期间,进程大多数时间都是处于等待的状态。所以就会处于S状态。
此时我们把printf删去,这个程序就只做死循环了,不会去访问任何外设,这时候进程就一直处于运行状态了。
进程后面+的含义:表示这个进程是前台进程。如果我们在运行可执行程序的时候后面加上&符合,这时就会变成后台进程,没有+进行标识了。此时进程进行CTRL+C是无法终止的,只能使用kill指令杀掉该进程。
- D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。(在资源极度紧张的情况,操作系统主动杀掉了进程,为了避免这种情况,就引入了这个状态,等磁盘工作完返回给进程,进程任务完成了才结束。),这个状态也属于阻塞状态,因为它在等待资源就绪。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
- t停止状态,这个状态一般在调试代码,对代码进行打断点的操作时,等待你的的下一步操作,此时进程就会处于t状态。(T/t也可以理解成一种阻塞状态,因为在这个状态进程也是在等待某种资源的就绪)
kill命令的第19号选项,就可以让进程暂停,在输入18号选项就可以就绪了。但被继续的进程会自动转为后台进程。下面是示例:
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
2.1僵尸和孤儿
- Z僵尸状态(zombie)
1.僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
2.僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
3.所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
来一个创建僵死进程例子:
#include <stdio.h> #include<stdlib.h> #include <unistd.h> int main() {pid_t id = fork();if (id == 0){//childint cnt = 5;while (cnt){printf("I am child,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);cnt--;}exit(0);//让子进程退出 }//fatherwhile (1){printf("I am father,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}return 0; }
编译并在另一个终端下启动监控
开始测试
看到结果
我们看到子进程已经进入僵尸状态了,此时子进程已经死了,只是还要维持到被父进程读取
为什么要有Z状态?
创建进程是希望这个进程给用户完成工作的,子进程必须有结果数据,PCB中的。
僵尸进程危害
- 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!
- 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB一直都要维护?是的!
- 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构
- 对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
- 内存泄漏
- 如何解决呢?在这里我们见一个函数wait,后面我们在详细的介绍
开始5s子进程和父进程一起进行,5s后子进程进入僵尸状态父进程,10s父进程结束执行wait函数(回收子进程资源,获取子进程状态)(bash创建的子进程bash会自动回收)
孤儿进程
- 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
- 父进程先退出,子进程就称之为“孤儿进程”
我们重新设置一下代码,让父进程先结束:
测试结果:
我们发现父进程结束后,子进程转为了后台进程,且父进程为”1“,1号进程其实就是操作系统,也就是说父进程结束后,它的子进程将会被操作系统领养。
3.进程的优先级
是什么?
前提:进程需要访问某种资源,进程通过一定的方式(排队),确认享受资源的先后顺序
为什么?
因为资源有限。
怎么办?
在Linux中,你可以使用多种方法来查看和修改进程的优先级。
在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
我们很容易注意到其中的几个重要信息,有下:
- UID : 代表执行者的身份
- PID : 代表这个进程的代号
- PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
- PRI :代表这个进程可被执行的优先级,其值越小越早被执行
- NI :代表这个进程的nice值
PRI and NI
- PRI也还是比较好理解的,即进程的优先级(Linux的默认优先级是80),或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高(Linux优先级的范围是:[60,99]--->40。)
- 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
- PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为: PRI(new)=PRI(old)+nice
- 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。
- 所以,调整进程优先级,在Linux下,就是调整进程nice值。
- nice其取值范围是-20至19,一共40个级别。
PRI vs NI
- 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
- 可以理解nice值是进程优先级的修正修正数据
用top命令更改已存在进程的nice:进入top后按“r”–>输入进程PID–>输入nice值
eg:初始状态
我给nice的值为10
此时PRI的值就为90了
Linux调整优先级为什么是要受限制的
如果不加限制,将自己进程的优先级调整的非常高,别人的优先级调整的非常低。优先级高的进程,优先得到资源--后续还有源源不断的进程产生,导致常规进程很难享受到CPU的资源!这就产生了进程饥饿问题。
4.Linux的调度与切换
概念准备:进程在运行的时候,放在CPU上,直接必须把进程代码跑完,才行吗?
不对,现代操作系统,都是基于时间片进行轮转执行的。
- 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
- 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
- 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
- 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
对于进程切换的理解:
进程切换,就像我们在日常生活中更换任务或活动一样,是操作系统中非常关键的一个环节。当我们从一个进程切换到另一个进程时,操作系统需要确保前一个进程的状态被保存下来,同时加载并恢复新进程的状态。
具体来说,进程切换涉及几个关键步骤。首先,系统会暂停当前正在运行的进程,保存其上下文信息,这包括CPU寄存器的内容、内存管理信息以及程序计数器等。这些信息对于进程的恢复和继续执行至关重要。(进程在执行的时候,它的数据是保存在CPU的寄存器中的。)
接下来,系统会选择一个新的进程来运行。这个选择过程可能基于多种因素,如进程的优先级、系统的调度策略等。一旦选择了新的进程,系统就会恢复其上下文信息(进程在运行的过程中,要产生大量的临时数据,放在cpu的寄存器中!cpu内部所有的临时数据,我们叫做进程的硬件上下文),将其状态设置为就绪状态,并将其加载到CPU中。
完成这些步骤后,新的进程就可以开始执行了。而原来的进程则处于暂停状态,等待下一次被调度执行。
进程切换的开销是相对较大的,因为涉及保存和恢复上下文信息、更新系统数据结构等操作。因此,操作系统会尽量优化进程切换的过程,减少不必要的开销,以提高系统的整体性能。(执行 保存 恢复 再执行)注意:cpu内的寄存器只有一套,寄存器内部保存的数据,可以有多套!虽然寄存器数据放在了一个共享的cpu设备里面,但所有的数据,其实都是被进程私有的!!!
cup内所有的数据在任意一个时刻只属于一个进程,怎么理解?
在任意一个时刻,CPU内的数据都属于当前正在执行的进程。这是操作系统通过进程调度和CPU管理实现的,确保了每个进程都能独占地使用CPU资源,并且其数据不会与其他进程的数据混淆或冲突。
需要注意的是,虽然CPU内的数据在任意时刻只属于一个进程,但在多核CPU系统中,每个核心可以同时执行不同的进程。这种情况下,每个核心的数据仍然只属于它当前执行的进程,但不同的核心可以同时处理不同进程的数据。(寄存器!=寄存器的内容)
对于调度的理解:
这是一个cpu的运行队列(Linux实现进程调度的算法,考虑优先级,考虑饥饿,考虑效率)
蓝色区域(表示活跃队列):时间片还没有结束的所有进程都按照优先级放在该队列
queue[140]:它是task_struc*类型,task_struct* queue[140] 是一个包含140个元素的数组,每个元素都是一个指向 task_struct 的指针,每个指针指向一个进程。它分为0-99,和100-139连个部分。
如果系统使用优先级调度,那么0-99这部分的队列可能用于存储优先级较高的进程,为了保证用户的公平性,这个区段的进程优先级都差不多。
100-139这部分包含数组的剩余40个元素。这些元素可能用于存储另一种类型的进程或任务(优先级较低的进程,处于不同状态的进程:这些进程可能处于阻塞状态,等待某些资源或事件。后台任务:这些可能是系统后台运行的任务,不需要立即执行)
为什么这里的范围刚好是40?因为进程的优先级刚好有40个等级,cup调用优先级只需要根据优先级依次去调用就好了。
bitmap[5]:(bitmap)常用于快速检查一个元素是否存在于某个集合中,或者用于高效地表示和管理大量的二进制数据。具体到bitmap[5],他是int类型的,那么他就有160个bit位,可以管理160个位置的信息。
如果bitmap[5]的某个位被设置为1,这可意味着该位置的资源已经被占用;如果设置为0,则表示该资源是空闲的。队列调度算法在决定下一个要执行的任务时,可能会查看这个bitmap来确定哪些资源是可用的,从而选择能够利用这些资源的任务。
bitmap[5]本身并不执行调度算法,它只是调度算法在决策过程中可能参考的一个数据点。实际的调度逻辑会更为复杂,可能涉及多个因素,如任务的优先级、资源的需求和可用性、系统的当前状态等。
红色区域(表示过期队列):这个结构和蓝色区域的一样,他也是一个优先级数组
过期队列和活跃列结构一模一样。
过期队列上放置的进程,都是时间片耗尽的进程。
当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算。
下面是对上面结构的理解,有一个q的结构体,我们封装成结构体数组,array[0]表示蓝色区域,array[1]表示红色区域。当活跃队列的进程只需完毕后,交换两个结构体指针的指向就好了,让过期队列的进程得以执行,这样就以O(1)的时间复杂度,实现了对进程的调度
相关文章:

Linux--进程(2)
目录 前言 1. 进程的状态 1.1 进程排队 1.2 运行,阻塞,挂起 2.Linux下具体的进程状态 2.1僵尸和孤儿 3.进程的优先级 4.Linux的调度与切换 前言 这篇继续来学习进程的其它知识 上篇文章:Linux--进程(1)-CS…...
贪心算法思想
求上下界极值: main(){对每一组输入数据计算比值的上下界,更新比值界限的极值全局最大的最小比值和全局最小的最大比值 }Note: V需要满足所有记录,所以取---->全局最大的最小比值和全局最小的最大比值 P9240 [蓝桥杯 2023 省 B] …...

PKI:构建数字安全基石的关键技术
在数字化时代,网络安全已成为我们日常生活和工作的重要组成部分。为了确保数据的完整性、机密性和身份的真实性,公钥基础设施(Public Key Infrastructure,简称PKI)技术应运而生,为构建数字安全基石提供了重…...
vue中实现路由鉴权和不同用户登录
路由鉴权 路由鉴权是指根据用户权限控制用户可以访问哪些路由。 Vue 中实现路由鉴权 Vue 中可以结合 Vuex 和路由守卫来实现路由鉴权。 1. 使用 Vuex 存储用户权限 创建一个 Vuex store 来存储用户权限。在登录成功后,将用户权限存储在 Vuex store 中。在路由守…...

Golang 开发实战day06 - Boolean Conditional
🏆个人专栏 🤺 leetcode 🧗 Leetcode Prime 🏇 Golang20天教程 🚴♂️ Java问题收集园地 🌴 成长感悟 欢迎大家观看,不执着于追求顶峰,只享受探索过程 Golang 教程06 - Boolean &a…...

内容多样化的秘密:Kompas.ai如何拓展你的内容形式
在这个信息爆炸的时代,内容多样化已成为品牌吸引和维系广泛受众的关键策略。多样化的内容形式不仅能够迎合不同用户的偏好,还能够提高内容的覆盖面和参与度,从而增强品牌的市场竞争力。本文将深入探讨内容形式多样化的重要性,展示…...
OneFlow深度学习框架介绍
OneFlow 是由中科院计算技术研究所和华为公司联合开发的开源深度学习框架,旨在为用户提供高效、灵活、易用的深度学习解决方案。以下是 OneFlow 深度学习框架的一些特点和介绍: 高性能:OneFlow 针对大规模模型和数据集进行了优化,…...

基于SSM的宠物管理系统
点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/89076676?spm=1001.2014.3001.5503 技术:SSM(Spring+SpringMVC+MyBatis)+LayUI+Echarts技术栈,分页采用pagehelper插件,EasyExcel进行Excel文件的导入导出。 宠物管理系统 1 CHINER-宠物管理系…...

【第十二篇】使用BurpSuite实现CSRF(实战案例)
CSRF存在前提:简单的身份验证只能保证请求是发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的 业务场景:新增、删除、收藏、编辑、保存使用Burp发现CSRF漏洞的过程如下。 1、如图,存在修改邮箱的功能点如下: 2、修改邮箱的流量包,此时邮箱已被修改: 思路:是…...
css 手写返回箭头
因为在开发App时,为了自定义返回栏,返回箭头,一般都用图片,当图片不方便,最好用css样式实现。 逻辑: 画出一个正方形,让它旋转45度,只显示你需要的两个边即可 代码 <!DOCTYPE ht…...

爬虫逆向非对称加密和对称加密案例
注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!! 案例--aHR0cHM6Ly9jcmVkaXQuaGxqLmdvdi5jbi94eWdzL3l6d2ZzeHF5bWQv 第一步:分析页面、请求…...

大数据基础设施搭建 - Spark
文章目录 一、解压压缩包二、修改配置文件conf/spark-env.sh三、测试提交Spark任务四、Spark on Hive配置4.1 创建hive-site.xml(spark/conf目录)4.2 查看hive的hive-site.xml配置与3.1配置的是否一致4.3 测试SparkSQL4.3.1 启动SparkSQL客户端ÿ…...

轻松上手Jackjson(珍藏版)
写在前面 虽然现在市面上有很多优秀的json解析库,但 Spring默认采用Jackson解析Json。 本文将通过一系列通俗易懂的代码示例,带你逐步掌握 Jackson 的基础用法、进阶技巧以及在实际项目中的应用场景。 一、Jackjson简介 Jackson 是当前用的比较广泛的&a…...

Pytorch数据结构:Tensor(张量)及其维度和数据类型
文章目录 Tensor基础1.1、Tensor的维度(Dimensions)1.1.1、举例说明1.1.2、高维Tensor 1.2、.dim()和.size()方法1.2.1、.dim()方法1.2.2、.size()方法1.2.3、.shape属性1.2.3、示例代码1.2.3.1、一维Tensor1.2.3.2、二维Tensor1.2.3.3、三维Tensor 1.3、…...

【THM】Protocols and Servers 2(协议和服务器 2
介绍 协议和服务器房间涵盖了许多协议: 远程登录HTTP协议文件传输协议邮件传输协议POP3IMAP实现这些协议的服务器会受到不同类型的攻击。仅举几例,请考虑: 嗅探攻击(网络数据包捕获)中间人 ( MITM ) 攻击密码攻击(身份验证攻击)漏洞从安全的角度来看,我们始终需要思考…...

阿里云服务器可以干什么?阿里云服务器主要用途是干嘛的?
阿里云服务器可以干嘛?能干啥你还不知道么!简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等,阿里云百科aliyunbaike.com整理阿里云服务器的用途: 阿里云服务器活动 aliyunbaike.com…...
LeetCode hoot100-22
160. 相交链表给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。这道题几分钟就写出来了。应该是几年前做过,这种思想还能一直记得。所以算法题是不会白做的。 我的…...

蓝桥杯 经验技巧篇
1. 注意事项 👨🏫 官方通知 👨🏫 资料文档 时间:4月13日 9:00~13:00 (时长 4小时)物品 准考证(赛前一周开放下载,自行打印)学生证身份证笔、水、外套&a…...

QMC5883芯片I2C驱动开发指南
这个芯片纯国产挺好用的,电路很好设计,我这垃圾焊功,纯手焊,,居然能用。 第一部分 硬件连接 画的很简陋,看看就可以了。 第二部分 软件驱动 I2C的具体时序实现需要自己搞定!! 2…...

缓存击穿以及解决方案
1.定义 缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。 问题描述:假设线程1在查询缓存之后,本来应该去查询数据库,然后把…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...