【Linux】对Linux操作系统中进程的理解

2023-11-11


需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。


 目录

一、冯·诺依曼体系结构(硬件方面)

举个例子加深理解

二、操作系统(软件方面)

1、操作系统的理解

2、系统调用和库函数的概念

三、进程控制块PCB的概念

四、进程的概念

1、什么是进程?

2、进程如何管理?

3、进程相关指令

3.1查看进程

3.2杀掉进程

3.3查看/proc文件系统

4、系统调用

4.1子进程getpid()

4.2父进程getppid()

4.3创建子进程fork()

五、进程状态的理解

1、什么是运行队列

2、对于CPU和硬件的速度差异,系统如何调度?

3、对于过多的阻塞进程,内存占用如何处理?

六、Linux操作系统的进程状态

1、进程状态在kernel中的定义

2、进程的运行状态 

3、进程的浅度睡眠状态(阻塞状态的一种)

4、进程的深度睡眠状态(磁盘休眠状态)(阻塞状态的一种)

5、进程的暂停状态/追踪暂停状态(阻塞状态的一种)

6、进程的僵尸状态/死亡状态

7、孤儿进程

七、进程的优先级

1、进程优先级的概念

2、nice值的修改

八、进程切换

1、进程特性

2、进程切换(并发)


一、冯·诺依曼体系结构(硬件方面)

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。

1、冯·诺依曼体系结构的存储器指内存,掉电易失。

2、而磁盘是一种外存,可以永久性存储数据。磁盘也属于外设的一种。外设又分为输入设备和输出设备。磁盘和网卡既是输入设备又是输出设备。

3、对于中央处理器,它有自己的指令集,外部程序翻译为CPU的指令集,让CPU根据这些指令集去执行。

4、 为了保证读取和写入速度,CPU只和内存打交道。

举个例子加深理解

现在我用我的电脑向我朋友的电脑传输一份压缩包文件。根据冯·诺依曼体系结构,将会经过以下流程:

二、操作系统(软件方面)

操作系统是管理软硬件的软件。

1、操作系统的理解

1、操作系统通过持续获取数据,进行软硬件的管理;

2、操作系统的管理的方法是先描述,再组织。先对被管理对象进行抽象成类,再根据这个类定义一个个具体的对象,再将这些对象通过数据结构进行关联,将软硬件的管理转换成对数据结构的管理。这其实也是面向对象的思想。

3、数据的采集和操作系统命令的下达,由驱动来做。

2、系统调用和库函数的概念

系统调用:从开发的角度,操作系统对外会表现为一个整体,但会暴露部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。

库函数:用户直接使用系统调用很困难,所以有了对系统调用进行封装的库函数。

三、进程控制块PCB的概念

1、我们写的可执行程序并不包含任何进程的属性信息。这些进程信息被放在一个叫做进程控制块的结构体中,用数据结构形成关联,可以理解为进程属性的集合;

2、该结构体被称之为PCB(process control block),Linux操作系统下的PCB是: task_struct;

四、进程的概念

1、什么是进程?

进程=内核数据结构(task_struct)+进程对应的磁盘代码和数据。

进程在调度运行的时候,就具有动态属性。

2、进程如何管理?

先描述,再组织。

操作系统会给每一个进程创建一个PCB对象,这些进程控制块对象用链表形成连接,通过遍历PCB的方式来找到对应状态的进程进行执行。例如找到优先级最高的PCB所对应的进程进行执行或通过PCB找到已死亡的进程进行释放。

通过这种方式,操作系统对进程的管理就变成了对进程所对应的PCB的管理,即链表的增删查改!

3、进程相关指令

3.1查看进程

ps axj | grep 'myproc'

能够显示出所有有关myproc的进程信息。

ps axj | head -1 && ps axj | grep 'myproc'

这个指令可以带上进程的小标题。

3.2杀掉进程

kill -9 8833

这里的8833是目标进程的PID。

3.3查看/proc文件系统

ll /proc/

/proc目录存在于内存中,这些数字名字的目录就是进程对应的PID。

ll /proc/14456 -d

能够找到正在运行中的PID14456的进程。

如果进程在运行时,可执行文件被删除,进程不会停止,但是进程目录中该可执行程序的路径将会无效。

4、系统调用

4.1子进程getpid()

#include <stdio.h>    
#include <unistd.h>    
#include <sys/types.h>                              
int main()    
{    
    while(1)    
    {    
        printf("hello world,MyPID=%d\n",getpid());
        sleep(1);
    }                
    return 0;
}  

调用getpid函数后,会将进程的PID打印出来

4.2父进程getppid()

#include <stdio.h>    
#include <unistd.h>    
#include <sys/types.h>                              
int main()    
{    
    while(1)    
    {    
        printf("hello world,MyPID=%d,MyPPID=%d\n",getpid(),getppid());
        sleep(1);
    }                
    return 0;
}  

可以发现,这个进程的父进程就是bash。命令行上启动的程序,一般它 的父进程没有特殊情况的话,都是bash。bash通过派生子进程的方式执行程序,如果程序有bug退出了,那挂掉的仅仅是子进程,bash没有影响。

4.3创建子进程fork()

#include <stdio.h>      
#include <unistd.h>      
#include <sys/types.h>      
int main()      
{    
    pid_t id=fork();    
    printf("MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);                                                                                                               
    return 0;                                 
}  

这个代码的执行结果是两个打印。

再看:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{    
                                                                    
    pid_t id=fork();                                                
    if(id==0)                                                       
    {                                                               
        //子进程    
        while(1)    
        {                                                                                                                       
            printf("子进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);    
            sleep(1);
        }                                                                      
    }                                                                                                  
    else if(id>0)                                                                                      
    {                                                                                                  
        //父进程                                                                                       
        while(1)                                                                                       
        {                                                                                              
            printf("父进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);      
            sleep(1);
        }                                                                                              
    }                                                                                                  
    else                                                                                               
    { 
    }
    return 0;
}

父子进程不断循环。说明fork()之后会有父子两个进程,fork()之后的代码,父子进程共享。

五、进程状态的理解

进程在不同的队列中,表示不同的状态。

1、什么是运行队列

1个CPU只有一个运行队列,进程的执行需要排队。让进程入队列,本质上是将task_struct结构体对象放入运行队列中。

这个进程队列中的指针可以找到需要加载的进程,将其PCB对象的信息加载到CPU中,CPU可以根据PCB对象的信息找到进程对应的代码进行执行。

在CPU的运行队列中的进程状态就叫做运行状态

状态,是进程的内部属性,存放于task_struct中。这个状态可以理解为一个整数,例如这个整数为1代表运行;2代表停止,3代表死亡状态等······

2、对于CPU和硬件的速度差异,系统如何调度?

进程不仅仅会占用CPU资源,也会占用硬件资源。对于CPU,它可以很快的处理进程的请求;但是对于硬件,速度很慢,例如网卡,可能同时有迅雷、百度网盘、QQ等进程需要获取网卡的资源,所以每一个描述硬件的结构体中也有一个task_struct* queue运行队列指针,指向排队中的PCB对象的头结点。

那么CPU和硬件的速度差异巨大,系统该怎么平衡这种速度?当CPU发现运行状态的进程需要访问硬件资源时,会让该进程去所需访问的硬件的运行队列中排队,CPU继续执行下一个进程。

那么这个被CPU剥离至硬件运行队列中的进程状态被称为阻塞状态。当进程对硬件的访问结束后,进程的状态将会被修改为运行状态,即该进程重新回到CPU的运行队列。

3、对于过多的阻塞进程,内存占用如何处理?

硬件的速度较慢,但是大量的进程需要访问硬件,势必会产生较多的阻塞进程,这些阻塞进程的代码和数据在短期内不会被执行,如果全部存在于内存中将会导致内存占用。

对于这个问题,如果内存中有过多的阻塞状态的进程导致内存不足,操作系统会将其的代码和数据先挪动至磁盘,仅留PCB结构体,以节省内存空间,这种进程状态被称为挂起状态。将进程相关数据,加载或保存至磁盘的过程,称为内存数据的换入和换出。

进程的阻塞状态不一定是挂起状态,部分操作系统可能会存在新建状态挂起或运行状态挂起等。

六、Linux操作系统的进程状态

1、进程状态在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 */
};

2、进程的运行状态 

#include <stdio.h>    
int main()    
{    
    while(1);                           
    return 0;    
}

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

状态后面有+号的表示前台进程,没有+号表示后台进程。前台进程在执行时,用户无法继续输入指令除非ctrl+c终止程序;后台进程在执行的过程中,用户可以输入指令且ctrl+c无法杀掉该进程。可以使用kill -9 PID的指令杀掉该进程。

3、进程的浅度睡眠状态(阻塞状态的一种)

浅度睡眠状态是可以被终止的进程状态。

#include <stdio.h>    
int main()    
{    
    int a=0;    
    while(1)    
    {    
        printf("%d\n",a++);               
    }                                  
    return 0;                          
} 

虽然数值一直在打印,但是printf函数需要访问显示器,大部分时间在等显示器IO就绪,只有小部分时间在执行打印代码。所以该代码呈现睡眠状态。

需要访问外设的,一般属于睡眠状态。

S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 【interruptible sleep】)。

那么有人会问了,为什么我的grep进程也处于S状态?博主试过多次执行该指令,grep进程有小概率会处于R状态,其实这个和他所查询的进程的状态也有关系,我在查询的进程在摸鱼,那我也去摸会鱼吧~

4、进程的深度睡眠状态(磁盘休眠状态)(阻塞状态的一种)

只有在高IO的情况下才会发生(Linux中有一个dd命令可以模拟高IO的状态,可以动手试逝)。

D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的

进程通常会等待IO的结束。

在该状态下的进程,无法被操作系统杀掉,只能通过断电或者进程自己醒来的方式中断深度睡眠状态。

5、进程的暂停状态/追踪暂停状态(阻塞状态的一种)

可以输入kill -19 PID来让一个进程进入暂停状态。或者将一个任务从前台切换到后台等,进程均会变为暂停状态。

T暂停状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。(kill -18 PID)

我们在使用gdb对一个可执行文件调试的时候,程序运行到断点处,程序会进入t追踪暂停状态(tracing stop):表示该进程正在被追踪。

6、进程的僵尸状态/死亡状态

Z僵尸状态(zombie):为什么会存在僵尸状态?因为进程在退出的时候,不会立即释放该进程对应的资源,会保存一段时间,让父进程或操作系统来读取子进程的返回代码。那么进程怎样进入僵尸状态?

模拟子进程正常退出,父进程不回收子进程(不读取子进程的返回信息)的场景(也可以使用kill -9 PID杀掉子进程):

#include <stdio.h>    
#include <unistd.h>    
#include <sys/types.h>    
#include <stdlib.h>    
int main()    
{    
    
    pid_t id=fork();    
    if(id==0)    
    {    
        //子进程    
        while(1)    
        {    
            printf("子进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);    
            sleep(1);    
            exit(1);    
        }    
    }                                                                                                                        
    else if(id>0)      
    {                          
        //父进程    
        while(1)      
        {  
            printf("父进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);
            sleep(1);   
        }
    }
    else 
    {
        perror("fork");
        exit(-1);                                                                                                            
    }
    return 0;
}  

通过该命令循环打印进程信息,发现子进程已经变成了僵尸状态。旁边的<defunct>译为死者,进程已经死亡,但是还未被回收,这就是僵尸状态。

僵尸进程的退出结果会写在PCB中,一个进程退出了,它的代码和数据会被释放,但是它的PCB是不会被释放,如果父进程不回收这块资源,那么会造成系统的内存泄漏。那我能不能手动杀掉这个僵尸进程来手动释放僵尸资源?不可以,因为僵尸进程已经死亡,无法手动杀掉进程。

在Z状态的进程被回收后,进程状态变为X死亡状态(dead):父进程读取完子进程的返回信息后,收尸速度太快了,我们看不到,进程死亡状态立马被它的父进程回收。

7、孤儿进程

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{

    pid_t id=fork();
    if(id==0)
    {
        //子进程
        while(1)
        {
            printf("子进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);
            sleep(1);
        }    
    }    
    else if(id>0)    
    {
        //父进程    
        while(1)                                                                         
        {    
            printf("父进程,MyPID=%d,MyPPID=%d,%d\n",getpid(),getppid(),id);    
            sleep(1);    
        }    
   }    
    else 
    {
        perror("fork");
        exit(-1);                                                                        
    }
    return 0;
}

前台创建的子进程,父进程被杀掉后,父进程立马被bash回收。子进程被1号进程(操作系统)领养,同时切换到后台运行(使用kill -9 PID杀掉后台进程)。因为不领养子进程的话,那么子进程退出时呈现的僵尸状态就没有谁能回收了(内存泄漏)。这种被领养的进程称为孤儿进程

七、进程的优先级

1、进程优先级的概念

进程的优先级本质就是PCB中的一个整数数字(不同操作系统可能由多个数字决定)。

使用ps -la命令显示出当前的进程信息。PRI(priority)代表优先级的意思(priority默认是80);NI(nice)用于调整优先级(nice默认是0)。

进程最终优先级=默认优先级(固定80)+nice值。

Linux支持进程在运行过程中调整优先级,调整的方式是修改nice值。

2、nice值的修改

注:1、需要root权限2、使用r调出修改nice值的命令栏。

nice的取值范围为【-20,19】,数字输的再小再大也没用。

所以Linux中进程的权限范围为【80-20,80+19】,数字越小,优先级越高。

进程优先级不要人为的调整,如果一个进程的优先级较高或较低,可能会造成其他进程获取操作系统资源不均,造成操作系统自身的调度失衡。

八、进程切换

1、进程特性

竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级 。

独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰 。

并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行 。

并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

2、进程切换(并发)

cpu中有一个eip寄存器(PC指针),指向下一条指令的地址。

进程在运行的时候,占有CPU,会产生很多的临时数据,归属于当前进程。虽然CPU内部仅有一套寄存器硬件,但是寄存器中保存的数据属于当前进程。(寄存器是共享的,但是数据是各进程私有的)

进程在运行的时候都有自己的时间片,这个时间一到,即使进程还没有被执行完毕,但是会被操作系统剥离CPU,腾出CPU让下一个进程上来跑一跑。

那么这个进程下次再回到CPU继续运行时,操作系统是如何知道这个进程的代码被执行到哪里了?

首先,进程在切换的时候,需要进行上下文保护,一些临时数据被保存至PCB里(误);进程在恢复运行的时候,要进行上下文的恢复,后续该进程回到CPU运行时,将加载这些数据。通过PC指针继续运行下一行代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】对Linux操作系统中进程的理解 的相关文章

  • __NR_gettid 和 SYS_gettid 之间的区别

    我只是在寻找在 Linux 中获取唯一线程 ID 的方法 我发现的方法是将两个参数中的任何一个作为参数进行系统调用 NR gettid OR SYS gettid 有人能解释一下它们之间有何不同吗 Nothing in
  • 如何在Linux中诊断Python进程占用CPU

    我的 python 进程在自动化脚本中的某个时刻开始在基于 Linux 的系统 Ubuntu 上占用 CPU 我正在尝试在 GDB 中调试这个问题 我对 GDB 还很陌生 是否有任何 GDB 命令可以提供有关哪个线程正在使用大部分 cpu
  • 无法从 Windows GUI 工具连接到远程 Linux 服务器上的 MySql 数据库

    我已经在 Amazon EC2 上的 Linux 服务器上设置了 mysql 数据库 这在本地效果很好 我可以登录 linux 盒子并管理 mysql 数据库 我正在尝试将本地 GUI 客户端连接到远程 mysql 但连接失败 我更新了 e
  • 如何在bash中使用kill SIGUSR2?

    我在linux中使用iptraf来监控网络流量 shell命令是 让iptraf在后台运行 iptraf s eth0 f B L traffic dat 如果我想得到结果 我必须先停止 iptraf 所以我使用 shell 命令 kill
  • 如何在 Ubuntu x64 中使用 ptrace 插入 int3?

    我正在努力追随本指南 http eli thegreenplace net 2011 01 27 how debuggers work part 2 breakpoints 通过设置断点达到相同的结果 唯一的区别是我在 x64 系统上 所以
  • 段错误...关于你好世界

    这段代码非常简单 但我在 x86 64 Linux 系统上遇到了段错误 这让我很烦恼 刚开始接触asm 请耐心等待 与 NASM 组装nasm f elf64 test asm 与连接ld o test test o SECTION tex
  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符
  • PIL 的 Image.show() 带来*两个*不同的查看器

    在 python shell 中处理图像时 我使用 image show 其中 image 是 Image 的实例 很久以前什么也没发生 但在定义了一个名为 xv 的 Mirage 符号链接后 我很高兴 最近几天 show 将显示 Imag
  • 我想在 Red Hat Linux 服务器中执行 .ps1 powershell 脚本

    我有一个在窗口中执行的 ps1 powershell 脚本 但我的整个数据都在 Linux 服务器中 有什么可能的方法可以让我在红帽服务器中执行 powershell 脚本 powershell脚本是 Clear Host path D D
  • 如何在Linux上用C/C++编写Web服务器[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在考虑在 Linux 平台上开发一个小型 阅读 初级 Web 服务器 但我不知道从哪里开始 我希望它能够做的是 监听特定端口 接受
  • Linux 内核使用的设备树文件 (dtb) 可视化工具? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个可以图形化表示Linux内核中使用的硬件设备树的工具 我正在尝试了解特定 Arm 芯片组
  • 如何获取与 shell 中的文件名模式匹配的所有文件的总文件大小?

    我正在尝试仅使用 shell 来计算与文件名模式匹配的所有文件 在目录树中 的总大小 以字节为单位 这是我到目前为止所拥有的 find name undo exec stat c s awk 总计 1 END 打印总计 有没有更简单的方法来
  • 使用 shell 脚本发送 HTML 邮件

    如何使用 shell 脚本发送 HTML 电子邮件 首先 您需要撰写消息 最低限度由这两个标头组成 MIME Version 1 0 Content Type text html 以及适当的消息正文 p Hello world p 获得后
  • 在本地主机上使用相同的 IP 和端口创建套接字

    我在 Linux 上看到奇怪的行为 我看到远程端和本地端都显示相同的 IP 和端口组合 以下是 netstat 输出 netstat anp 网络统计grep 6102 tcp 0 0 139 185 44 123 61020 0 0 0
  • 在ubuntu中打开spyder

    我想在ubuntu中打开spyder Python IDE 通常我会在 shell 中编写 spyder 它会打开spyder IDE 现在 当我在shell中编写spyder时 它只是换行 什么也没有发生 类似于按 enter 我如何找回
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • LINUX:如何锁定内存中进程的页面

    我有一个 LINUX 服务器 运行一个具有大量内存占用的进程 某种数据库引擎 该进程分配的内存太大 需要将其中一部分换出 换出 我想做的是将所有其他进程 或正在运行的进程的子集 的内存页面锁定在内存中 以便只有数据库进程的页面被换出 例如
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 如何在线程创建和退出时调用函数?

    include

随机推荐

  • 深度优先查找和广度优先查找

    深度优先查找和广度优先查找 在人工智能和运筹学的领域中求解与图有关的许多应用中 这两个算法被 证明是非常有用的 并且 如需高效地研究图的基本性质 例如图的连通性以及图是否存 在环 这些算法也是必不可少的 深度优先查找 深度优先查找可以从任意
  • python之cv2与图像的载入、显示和保存

    本文是OpenCV 2 Computer Vision Application Programming Cookbook读书笔记的第一篇 在笔记中将以Python语言改写每章的代码 PythonOpenCV的配置这里就不介绍了 注意 现在O
  • shell-if语句详解

    if 条件 then Command else Command fi 别忘了这个结尾 If语句忘了结尾fi test sh line 14 syntax error unexpected end of fi if 的三种条件表达式 if c
  • navigator.geolocation.getCurrentPosition在谷歌浏览器不执行的问题

    在React 中使用navigator geolocation getCurrentPosition去获取定位信息时 获取地理位置信息 navigator geolocation getCurrentPosition position gt
  • 初识SQL workbench

    一 workbench 下载地址 https dev mysql com downloads workbench 二 环境变量配置 双击安装包 点击 Next 进行安装 重要提醒 请截图保留安装界面中 见下图 红色框起来的地址 图1 记住安
  • 3打包生成dist文件夹并发布到服务器

    打包生成dist文件夹并发布到服务器 打包生成dist文件夹 npm run build 发布1 使用静态服务器工具包 安装serve npm install g serve serve dist 访问 http localhost 500
  • mac下搭建编译chromium的开发环境

    本篇为 mac 下搭建编译chromium的方法 windows篇 windows下搭建编译chromium的开发环境 二七 CSDN博客 linux篇 linux 搭建和编译 chromium 环境 二七 CSDN博客 系统环境 mac
  • 如何实现自定义MVC框架(最终版本)

    目录 一 将MVC框架源码导成jar包 1 1优化的思路 1 2具体步骤 二 创建需要的工具包 分析思路 具体的代码 三 总结 前言 我们通过框架的形式实现一个具有增删改查的网页 一 将MVC框架源码导成jar包 1 1优化的思路 相比我们
  • Selenium自动化测试简介

    IT赶路人专注分享跟IT相关的各种知识 希望我们一起学习 共同成长 Selenium自动化测试 很早就想跟大家分享 在15年开始 我们的团队就在使用这个工具 最初 我们使用的语言是Java和SQL的结合 随后 随着最近几年Python语言的
  • Leetcode 219. Contains Duplicate II (hashmap 和 sliding window)

    Contains Duplicate II Easy Given an integer array nums and an integer k return true if there are two distinct indices i
  • ElasticSearch 绑定IP地址

    https blog csdn net yelllowcong article details 78740237
  • Dx11--用dx11绘制棱台,并用键盘和鼠标进行旋转缩放操作

    目录 一 索引缓冲区 前言 创建缓冲区 缓冲区的描述 二 常量缓冲区 前言 准备工作 正式初始化 画面更新及其效果 画面更新 效果 三 键盘和鼠标的创建 1 鼠标的创建 2 键盘的创建 3 更新画面 4 消息回调函数 处理键盘鼠标信息 效果
  • Python协程介绍【赠书活动|第五期《Python编程入门与实战》】

    文章目录 一 相关概念 1 协程 2 子程序 3 区别 4 协程的优势 二 示例 赠书活动 一 相关概念 1 协程 协程 又称微线程 纤程 英文名Coroutine 协程的概念很早就提出来了 但直到最近几年才在某些语言 如Lua 中得到广泛
  • LeetCode : Search for a Range

    Given a sorted array of integers find the starting and ending position of a given target value Your algorithm s runtime
  • Centos7安装jdk1.8

    Centos7安装jdk1 8 两种安装方式 1 检查本机是否安装了jdk 安装了就不用安装了 命令如下 root localhost java version bash java 未找到命令 root localhost 注意 说明未安装
  • 视频解码学习备忘

    媒体文件知识 日常都是播放器直接播 其实这里面还有不少内容的 首先是视频容器 就是所谓的 mp4 mkv 这类文件 其目的主要就是用来存放音频视频字幕等内容 所以叫做容器 这些都有一定规范 比如mp4 叫ISO 14496 12 也即是mp
  • 7-1 图的先深搜索+7-2 图的先广搜索

    由于本人用指针 链表实现数据结构算法时经常有使用堆叠字节的警告以及栈溢出报错 于是就都用数组或者C stl模拟了 输出无向图的给定起点的先广序列 输入格式 输入第一行给出三个正整数 分别表示无向图的节点数N 1
  • C语言-按照单词反转字符串(完整代码)

    编程实现以单词 为单位的字符串逆序 例如 HELLO WORLD WORLD HELLO 目录 实现逻辑 实现代码如下 完整备注 执行结果如下 实现逻辑 当前的实现逻辑 是通过两个指针变量 一个指针
  • 第十二讲:强化学习(Reinforcement Learning)和控制(Control)

    这一章我们就要学习强化学习 reinforcement learning 和适应性控制 adaptive control 了 在监督学习 supervised learning 中 我们已经见过的一些算法 输出的标签类 y y y 都是在训
  • 【Linux】对Linux操作系统中进程的理解

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 冯 诺依曼体系结构 硬件方面 举个例子加深理解 二 操