【Linux】进程状态|优先级|进程切换|环境变量
文章目录
- 1. 运行队列和运行状态
- 2. 进程状态
- 3. 两种特殊的进程
- 僵尸进程
- 孤儿进程
- 4. 进程优先级
- 5. 进程切换
- 进程特性
- 进程切换
- 6. 环境变量的基本概念
- 7. PATH环境变量
- 8. 设置和获取环境变量
- 9. 命令行参数
1. 运行队列和运行状态
💕 运行队列:
进程是如何在CPU上运行的:CPU在内核上维护了一个运行队列,进行进程的管理。让进程进入队列,本质就是将该进程的task_struct 结构体对象放入运行队列之中。这个队列在内存中,由操作系统自己维护。

💕 运行状态:
运行状态进程PCB在运行队列里就是运行状态,不是说这个进程正在运行,才是运行状态。状态是进程内部的属性,所有的属性在PCB里,进程不只是占用CPU资源,也有可能随时要外设资源。阻塞状态进程因为等待某种条件就绪而导致的一种不推进的状态——进程卡住了,此时的进程要通过等待的方式,等待具体的资源被别人用完之后,再被自己使用。阻塞状态进程的PCB被放在硬件的等待队列中。本质是对tack_struct对象放到不同的队列中!
挂起状态如果系统中存在许多进程,进程短期内不会被调度,代码和数据在短期内不会被执行,此时如果内存空间不足,操作系统就可以把代码和数据暂时保存到磁盘上,节省一部分空间,该进程暂时被挂起了,这就是挂起状态。对于阻塞状态和挂起状态,阻塞不一定挂起,挂起一定是阻塞。
因此,所谓的进程不同的状态,本质是进程在不同的队列之中,等待某种资源。
2. 进程状态
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在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)。D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。Z僵尸状态(zombie):这个状态是一个已经运行完的子进程,等待父进程回收他的返回值。
💕 运行状态R:


💕 睡眠状态S:

当我们执行可执行程序后,在使用ps命令查看进程状态时,发现他是S状态,为什么我们的程序正在运行,进程却是睡眠状态呢?

这是因为我们使用printf进行打印时,需要访问外设,但外设的速度是远远低于CPU的,所以进程大部分时间都在等待硬件资源的就绪,所以我们每次查看时,进程几乎都处于阻塞状态。
💕 磁盘休眠状态D:
当内存中的空间不足时,操作系统会让一些进程进入挂起状态,但是,如果内存的空间严重不足时,进程挂起也解决不了问题,这个时候操作系统可能会将一些暂时挂起的进程或者没有被调度的进程杀掉。
但是如果要是此时挂起的进程正在向磁盘写入数据,或者进行一些重要的数据传递时,如果操作系统将这个进程杀死,那么磁盘就可能会将正在传递的数据丢弃,此时重要的数据就有可能因为操作系统将进程杀死导致重要数据的丢失。所以,我们的深度睡眠状态就是针对这种情况而生的。深度睡眠状态下的进程既不能被用户杀死,操作系统也无法将其杀死。只能通过断点,或者等待进程自己醒过来。
💕 暂停状态T:
暂定状态也是阻塞状态的一种,下面我们来看一下如何让一个运行状态下的进程暂停:

我们可以使用kill的19号指令将一个进程从运行状态变为暂停状态。


如果想要使得休眠中的进程重新恢复运行状态只需要执行kill的18号命令即可:

这里我们可以看到进程又重新进入了运行状态,但是为什么进程重新进入云心状态后后面的 +号 消失了呢?
其实,进程状态后面的 +号 表示的是这个进程是一个前台进程,如果没有 +号就表示这个进程是一个后台进程。对于前台进程我们可以使用Ctrl + c将其杀死,但是对于后台进程,我们只能使用kill命令杀死他。
💕 追踪暂停状态t:
属于暂停状态的一种,表示进程正在被追踪。最典型的一种就是gdb调试进程的时候。
💕 死亡状态X:
表示一个进程结束运行,他的PCB以及代码和数据全部都被操作系统回收。
💕 僵尸状态Z:
一个进程在退出的时候,不能立即释放全部的资源,但是该进程已经不会再被执行了,该进程的PCB中存放着他的各种各样的状态码,尤其是退出状态码。
僵尸状态就是为了在进程退出的时候能够让父进程或者操作系统拿到他退出状态码,然后释放PCB的一种状态。
3. 两种特殊的进程
僵尸进程
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
下面我们来举例看一下僵尸进程:


当我们杀掉子进程后,由于父进程并没有读取子进程的退出状态码,所以子进程进入了Z(僵尸状态),如果父进程一直不读取子进程的退出状态码,那么子进程就会变成僵尸进程。

僵尸进程的危害:
父进程如果一直不读取子进程的退出状态码,那子进程就一直处于Z状态。维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中。换句话说, Z状态一直不退出, PCB一直都要维护。那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。
孤儿进程
父进程如果提前退出,那么子进程就会被操作系统领养,此时的子进程就称之为“
孤儿进程”,孤儿进程被1号init进程领养,最后由init进程回收。

这里我们可以看到:如果将父进程杀死后,父进程并不会进入僵尸状态,这是因为父进程在退出后会被父进程的父进程——bash所读取他的退出状态码。还有子进程被1号进程领养后会由前台进程变成后台进程。
4. 进程优先级
CPU的资源是有限的,但是内存中有很多进程都需要占用资源,所以需要给进程指定优先级来合理的分配资源。
CPU资源分配的先后顺序,就是指进程的优先级(priority)。优先级高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

当我们输入ps -l/ps -al指令后就可以看到进程优先级相关的属性:
UID: 代表执行者的身份PID: 代表这个进程的代号PPID:该进程的父进程的代号PRI:代表这个进程可被执行的优先级,其值越小越早被执行NI:代表这个进程的nice值
下面我们重点介绍一下PRI和NI这两个变量,PRI(priority) 即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。而NI(nice) 表示进程可被执行的优先级的修正数值。需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据。
PRI值越小越快被执行,那么加入NI值后,将会使得PRI变为: PRI(new)=PRI(old)+NI,这里我们需要注意的是:每个进程默认的PRI都是80,NI都是0,但是NI的波动范围是:[-20,19],PRI与NI的和越小,进程的优先级越高。
下面我们来看一下如何修改进程的优先级:
(1) 输入top指令

(2) 输入r

(3) 输入进程的id

(4) 输入NI值

这里我们还需要注意的是:普通用户无法直接修改NI的值,必须切换成root用户或者使用sudo提权执行top指令。
5. 进程切换
进程特性
- 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
- 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
- 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
- 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。
进程切换
一个CPU里面存在一套硬件寄存器,宏观上寄存器分为用户可见,用户不可见。
计算机调度某个进程时,CPU会把这个进程的PCB地址加载到某个寄存器,也就是说,CPU内有寄存器可以只找到进程的PCB地址。
CPU里有一个eip寄存器(PC指针),指向当前执行指令的下一条指令的地址。
而进程运行的时候一定会产生很多的临时数据,但这些临时数据只属于当前进程,虽然CPU内部只有一套寄存器硬件,但是寄存器保存的数据只属于当前进程,也就是说,寄存器硬件不是寄存器内的数据,这是两码事,寄存器被所有进程共享,但是寄存器里的数据时每个进程各自私有的。
时间片引出——进程在运行的时候占有CPU,但是却不是一直占有到进程结束,进程都有自己的时间片!因为时间片的存在,进程会出现没有被执行完就被拿下去的情况,这时候问题来了:这个进程下一次如何在次回到CPU继续运行:
进程切换的时候,需要先进行上下文保护,这里的上下文指的是CPU里的寄存器的数据,而不是寄存器,这里简单理解为临时数据保存至PCB里,而当进程恢复运行的时候,要进行上下文的恢复,该进程在次回到CPU继续运行时,重新加载恢复这些数据。
6. 环境变量的基本概念
环境变量(environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数。
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
当我们平常执行自己的可执行程序时,必须在前面指定路径来执行,但是执行Linux中的指令时,并不需要指定路径,这是什么原因呢?


其实,在Linux下的各种指令和我们平常自己编写代码生成的可执行程序没有什么区别,他也是个可执行程序,但是因为系统中存在PATH环境变量,这些指令的地址都被存放在环境变量中,当我们调用这些指令时,系统会自定去PATH中寻找这些指令。
7. PATH环境变量
PATH是由一堆目录组成的,各目录之间用冒号 “
:” 隔开。 当执行某个 Linux 命令时,Linux 会依照 PATH 环境变量中包含的目录依次搜寻该命令的可执行文件,一旦找到,即正常执行;反之,则提示无法找到该命令。
💕 查看环境变量:echo $PATH

💕 添加PATH环境变量:
(1) 直接添加

一般不建议使用这种方法添加,因为我们写的程序没有经过测试,容易污染指令池。
(2) 使用export命令添加

在这里我们还需要注意的是,我们不能直接写成这样:export PATH=/home/Chenjiale/lesson2-22,这样会导致把系统默认的环境变量PATH覆盖掉,我们默认的那些指令就不能直接使用了,只能通过指定路径的方式来使用。
💕 系统中的其他环境变量:
- HOSTNAME: 主机名
- USER: 当前用户名
- PWD: 当前系统路径
- HOME: 当前用户的家目录
- HISTSIZE: shell 能记忆的最多历史命令的条数
查看所有的环境变量:env指令

下面我们来看一下环境变量是在系统中的哪个文件夹下面的:

实际上,当我们在登录 shell 时,操作系统会让我们当前的 shell 进程执行 .bash_profile 中的内容,而 .bash_profile 又会调用执行 .bashrc,它们会将对应的环境变量导入到 shell 进程的上下文环境中。所以,如果我们上面不小心将 $PATH 覆盖掉了也不用担心,重新登录 shell 就好了。
环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量,这些变量往往具有特殊功能,且能够一直被 bash 以及 bash 的子进程访问。环境变量具有全局属性的根本原因是环境变量会被子进程继承。
8. 设置和获取环境变量
💕 设置和取消环境变量:
如果我们直接在命令行中定义一个变量,那么这个变量则是本地变量,本地变量只在bash进程中有效。

当然我们可以使用export直接将本地变量设置为环境变量,同时,也可以直接使用export来定义一个环境变量。
export 已存在的环境变量: 将本地变量设置为环境变量
export 新的变量: 直接定义一个环境变量

如果我们不想要这个变量,可以直接使用unset指令来取消变量,当然我们也可以使用set指令来查看所有变量。

💕 获取环境变量:
获取环境变量除了可以使用echo $环境变量名之外,还可以使用一个函数getenv()来获取。

下面我们举例来演示一下:


在命令行上运行mytest时候,bash就是一个系统进程,mytest也会变成一个进程(通过fork创建父子进程),是bash的子进程。而环境变量具有全局属性的根本原因是会被子进程继承下去,因为环境变量定义给bash,而子进程会全部继承下去,这就被称为环境变量。所以环境变量具有全局性,而本地变量只会在当前进程(bash内)有效。
为了不同的应用场景,让bash替我们寻找指令路径,例如:身份认证;有些子进程需要用到这些信息,确认当前用户的信息。
下面我们来举一个例子:


这里我们一定要使用su -来验证,我们可以使用getenv函数来获得当前的Linux用户,判断其是否具有某种权限,然后再执行对应的操作。
9. 命令行参数
我们知道在C语言中,main函数也是有参数的,不过我们平常一般都不需要手动传参,而是被系统/父进行行传参的。所以,这个参数可能会被大多数人忽略。
int main(int argc,char* argv[],char* env[])
这里我们可以先来看一下前两个参数,第一个参数是指第二个参数——指针数组中的元素个数。这里我们可以先来看一下指针数组中的每一个元素存的是什么。


其实这里的argv中的每一个元素都指向的是一个字符串,argc用来指定数组中元素的个数,他们配合可以使用-a -b -c 类似的选项功能。
下面我们来看一下最后一个指针数组中的内容:


这里我们看到的是:打印出来的就是环境变量的内容。这是因为env接收的就是父进程传递过来的环境变量的参数。
最后,还有一种获取环境变量内容的方式就是通过环境变量表environ,这里我们直接来验证一下即可。



相关文章:
【Linux】进程状态|优先级|进程切换|环境变量
文章目录1. 运行队列和运行状态2. 进程状态3. 两种特殊的进程僵尸进程孤儿进程4. 进程优先级5. 进程切换进程特性进程切换6. 环境变量的基本概念7. PATH环境变量8. 设置和获取环境变量9. 命令行参数1. 运行队列和运行状态 💕 运行队列: 进程是如何在CP…...
合宙Air780E|FTP|内网穿透|命令测试|LuatOS-SOC接口|官方demo|学习(18):FTP命令及应用
1、FTP服务器准备 本机为win11系统,利用IIS搭建FTP服务器。 搭建方式可参考博文:windows系统搭建FTP服务器教程 windows系统搭建FTP服务器教程_程序员路遥的博客-CSDN博客_windows服务器安装ftp 设置完成后,测试FTP(已正常访问…...
大规模 IoT 边缘容器集群管理的几种架构-4-Kubeedge
前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介大规模 IoT 边缘容器集群管理的几种架构-1-RancherK3s大规模 IoT 边缘容器集群管理的几种架构-2-HashiCorp 解决方案 Nomad大规模 IoT 边缘容器集群管理的几种架构-3-Portainer 📚️Reference…...
Spring底层核心原理解析
Spring简介 ClassPathXmlApplicationContext context new classPathXmlApplicationContext("spring.xml"); UserService userService (UserService) context.getBean("userService"); userService.test();上面一段代码是我们开始学习spring时看到的&…...
OpenStack手动分布式部署Glance【Queens版】
目录 Glance简介 1、登录数据库配置(在controller执行) 1.1登录数据库 1.2数据库里创建glance 1.3授权对glance数据库的正确访问 1.4退出数据库 1.5创建glance用户密码为000000 1.6增加admin角色 1.7创建glance服务 1.8创建镜像服务API端点 2、安装gla…...
谈一谈你对View的认识和View的工作流程
都2023年了,不会还有人不知道什么是View吧,不会吧,不会吧。按我以往的面试经验来看,View被问到的概率不比Activity低多少哦,个人感觉View在Android中的重要性也和Activity不相上下,所以这篇文章将介绍下Vie…...
Redis集群的脑裂问题
集群脑裂导致数据丢失怎么办? 什么是脑裂? 先来理解集群的脑裂现象,这就好比一个人有两个大脑,那么到底受谁控制呢? 那么在 Redis 中,集群脑裂产生数据丢失的现象是怎样的呢? 在 Redis 主从架…...
互斥信号+任务临界创建+任务锁
普通信号量 1、信号量概念 2、创建信号量函数 3、互斥信号量 创建互斥信号量函数 等待信号量函数 释放互斥信号量 4、创建任务临界区 5、任务锁 任务上锁函数 编辑 任务结束函数 效果 普通信号量 1、信号量概念 信号量像是一种上锁机制,代码必须获…...
Elasticsearch7.8.0版本进阶——文档搜索
目录一、文档搜索的概述二、倒排索引不可变的优点三、倒排索引不可变的优点一、文档搜索的概述 早期的全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。 一旦新的索引就绪,旧的就会被其替换,这样最近的变化便可以被检索到。倒排索引被…...
spring security权限问题
org.springframework.boot spring-boot-starter-security 引入jar extends WebSecurityConfigurerAdapter 用来配置登陆和权限 configure(HttpSecurity http) 覆盖这个方法 //配置授权相关的 .authorizeRequests () //任何请求 .anyRequest() //要求授权后可以访问 .authen…...
mysql 8.0.22安装
mysql8.0.22安装1. 配置my.ini2. 添加环境变量3. 安装mysql3.1 mysql初始化3.2 安装mysql服务3.3 启动mysql服务4. 连接数据库修改连接数据库的密码前提:已经从官网下载mysql8.0.22安装包并解压(下载地址:https://dev.mysql.com/downloads/in…...
Mysql系列:Mysql5.7编译安装
系统环境:Centos7 1:下载mysql源码包 https://dev.mysql.com/downloads/mysql/5.7.html downloads 选择MySQL Community Server>source_code>Generic Linux (Architecture Independent), Compressed TAR Archive -> 选择需要的mysql版本&…...
设备树(配合LED驱动说明)
目录 一、起源 二、基本组成 三、基本语法 四、特殊节点 4.1 根节点 4.2 /memory 4.3 /chosen 4.4 /cpus 多核CPU支持 五、常用属性 5.1 phandle 5.2 地址 --------------- 重要 5.3 compatible --------------- 重要 5.4 中断 --------------- 重要 5.5 …...
(二十六)大白话如何从底层原理解决生产的Too many connections故障?
今天我们继续讲解昨天的那个案例背景,其实就是经典的Too many connections故障,他的核心就是linux的文件句柄限制,导致了MySQL的最大连接数被限制,那么今天来讲讲怎么解决这个问题。 其实核心就是一行命令: ulimit -H…...
ASEMI高压MOS管60R380参数,60R380特征,60R380应用
编辑-Z ASEMI高压MOS管60R380参数: 型号:60R380 漏极-源极电压(VDS):600V 栅源电压(VGS):20V 漏极电流(ID):11A 功耗(PD&#x…...
Python期末试卷
《Python程序设计基础》期末试题 班级 学号 姓名 一.选择题(须知:答案写到下方的表格中,其它一律无效.每题2分,共40分) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 1.在Python交互…...
Linux | 网络通信 | http协议介绍 | cookie策略讲解
文章目录url统一资源定位符http协议介绍GET vs POSThttp状态码http常见headercookie session上篇博客定制了一个协议,该协议用来进行简单的计算,其包含了数据的序列化和反序列化,编码和解码的定制,并且该协议基于TCP通信…...
招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
winapi获取和修改camera raw界面元素数据
camera raw 界面如下: 需求就是根据 windows api 来操作界面右边的色温、色调、曝光等属性,进而对图片进行调色。根据 spy 捕获的窗口信息,理论上是可以拿到并修改值的。 根据 class 可以先拿到窗口句柄: #define CAMERA_RAW_CLA…...
C++问答汇总_2023自用
C是一种通用编程语言,具有高级抽象、强类型和编译性能等特点。C语言具有许多特性,包括面向对象编程、模板、多态、运算符重载等等。它广泛应用于各种领域,如系统软件、嵌入式系统、游戏开发、科学计算等等。 1、C11相对于C98的新特性…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...


