【Linux】进程基础

2023-11-16


在这里插入图片描述

1.冯诺依曼体系

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

image-20220808212343448

组成部分

  • 输入设备:键盘、话筒、摄像头、磁盘、网卡…
  • 输出设备:显示器,音响,磁盘,网卡,显卡…
  • 中央处理器(CPU):算数计算+逻辑运算
  • 存储器:内存

为什么要有内存?

  • 1.从技术的角度:

    • CPU的运算速度 > 寄存器的速度 > L1~L3Cache【三级缓存】> 内存 > 外设【磁盘】> 光盘磁带
    • 外设不会之间和CPU交互,而是先和内存交互。然后CPU再和内存进行交互
    • 从整个内存来看,整个体系结构就是一个大的缓存,解决外设和CPU速度不匹配的问题
  • 2.从成本角度

    • 寄存器 > 缓存 > 内存 > 外设
1.2操作系统

操作系统包括:

  • 内核:内存管理,进程管理,文件管理,驱动管理
  • 其他程序

操作系统可以看成是管理软件的软件。

image-20220808213247931

  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分
    由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统
    调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发

2.进程

2.1进程的概念
  • 进程是一个运行起来的程序(程序是一个可执行的文件)
  • 内核:担当分配系统资源(CPU时间,内存)的实体。
  • 进程=可执行文件+描述进程的数据结构(task_struct)

为什么管理描述进程要有-PCB(process ctrl block)?
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block),Linux操作系统下的PCB是task_struct 。(因为Linux内核是用C语言写的,所以Linux管理内核就使用一个结构体存储一个进程的信息,以便管理)

  • 在Linux中,所有运行在系统里的进程都以task_struct链表的形式存在内核里

查看进程

查看进程
ls /proc
也可以使用psc
ps ajx

image-20220808213614762

2.2 task_struct

task_ struct内容分类

  • 标示符pid: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态state: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共有的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

为什么父进程的父进程不变?

所有进程的最终父进程是bash进程,几乎我们在命令行上所执行的所有的指令(cmd),都是bash进程的子进程。

为什么fork(),子进程会返回0,而父进程会返回子进程的pid?

子进程的task_struct对象,内部的数据基本上都是从父进程拷贝而来的。fork()之后,父子进程的代码共享,但是一般都通过不同的返回值,让不同的进程执行不同的代码。【而数据是各自独立】

如何理解进程被运行?

理解调度器和调度队列(runqueue)

  • 创建进程
  • 放入运行队列
2.3进程的状态

操作系统层面的进程的状态status

image-20220705015259759

  • 进程运行:并不意味着进程一定在运行中,它表明进程要么是在运行中要么在调度【运行】队列里。
  • 进程终止:表示这个进制永远不再使用,随时等待被释放
  • 进程阻塞:
    • 1.一个进程,在使用资源的时候,不仅仅要申请CPU资源
    • 2.进程可能要申请更多的其他资源:磁盘、网卡、显卡、显示器资源…
    • 3.在申请CPU资源的时候,可能暂时无法得到满足,需要排队-----运行队列
    • 4.如果要申请其他的慢资源(比如外设)------也需要进行排队【申请各个资源的等待队列】(task_struct排队)。
    • 5.当进程申请其他某些资源,而资源暂时没有准备好,或者在为其他进程提供服务。此时:1.当前进程要从runqueue中移除。2.将进程的task_struct放入对应设备的描述结构体中的等待队列。
    • 6.当进程在等待某种资源的时候,资源没有就绪,进程需要在该资源的等待队列中进行排队,进程的代码不会被执行,也就是进程阻塞。
  • 进程挂起:
    • 当进程过多时,内存可能不足,这是OS就会对部分进程进行辗转腾挪
    • 短期时间不会被调度的进程(可能是因为某资源的等待队列过长,短期内无法申请到某资源),它的代码和数据依旧在内存中占用资源,就是白白的浪费空间。OS就会把进程的代码和数据从内存置换到磁盘中【磁盘中有一个专门存放置换进程代码和数据的分区,叫做swap分区】。
    • 因为内存不足和展示不被调度,而导致进程的数据置换到磁盘的swap分区,就叫做进程挂起。

系统为什么要维护一个终止态?

  • 可能系统需要进程终止的信息
  • 释放进程需要时间,可能此时操作系统比较繁忙。
  • 该状态下,进程永远也不运行,随时等待被释放。

Linux的进程状态state

task_struct中使用task_state_array[]数组存放状态变量
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 */[重点]
};

image-20220809175358359

  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping)-----对应阻塞状态: 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep)),该进程可以被OS杀死
  • D磁盘休眠状态(Disk sleep)-----对应阻塞状态:有时候也叫不可中断睡眠状态(uninterruptible sleep),**此状态下OS无法杀死该进程,**在这个状态的进程通常会等待IO的结束。
    • 一般而言,Linux中,如果我们等待的是磁盘资源,进程阻塞的状态就是D。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
  • t(tracing stop):也是停止状态,是调试状态下的暂停状态。
  • X死亡状态(dead):这个状态只是一个返回状态,进程可以被释放,你不会在任务列表里看到这个状态。
  • Z僵尸状态(zombie):在Linux中,一个进程退出的时候,一般不会直接进入X状态(死亡状态,资源立马回收),而是进入Z状态。
    • 为什么?
    • 一个进程被创建出来,一定是因为要有认为让这个进程执行,当该进程退出的时候,需要告知父进程和OS执行任务的情况。
    • 进程进入Z状态,就是为了维护退出信息,可以让父进程或者OS读取
    • 僵尸进程就是Z状态。
    • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护。
    • 那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间 。

孤儿进程:父进程先死,子进程还没有被杀掉。子进程会被1号进程领养。而1号进程就是【操作系统】。

进程的大部分时间都在等待申请资源

int main()
{
    printf("begin.....\n");
    while(1)
    {
        
    }
    return 0;
}

在这里插入图片描述

int main()
{
    printf("begin.....\n");
    while(1)
    {
        printf("hello world\n");
    }
    return 0;
}
ps ajx | head -1 && ps ajx | grep hello

在这里插入图片描述

表明进程大部分的时间都在申请资源。

2.4进程优先级
优先级VS权限

优先级是进程获取资源的先后顺序。

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
为何会存在优先级

资源不够。系统里面永远都是,进程占大多数,而资源是少数。

Linux下的优先级相关概念
ps -la

image-20220810174242329

相关概念

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值

PRI和NI

  • PRI,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • NI,就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值;nice其取值范围是-20至19,一共40个级别。Linux给用户用的进程优先级范围是80-100。
  • 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  • 可以理解nice值是进程优先级的修正修正数据

**用top命令更改已存在进程的nice **

  • top
  • 进入top后按“r”–>输入进程PID–>输入nice值
  • 或者PID to renice
  • Linux不允许用户无节制的设置优先级
2.5其他重要概念

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

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

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

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

单道和多道程序设计

单道程序设计:一次只有一个处于程序在运行中;其他程序处于等待状态。(DOS)

多道程序设计:设计出时间片,在一个时间片中执行一个程序,在下一个时间片立马然后切换为下一个程序,从而让出cpu的资源给其他程序。

由于一个时间片的时间很短,属于是毫秒级别的。所以在人的感知上,几个程序是并发进行的;但是在微观上,在一个时间片上,只有一个程序在运行。微观上串行,宏观上并行

image-20220705013224488

进程的切换是依靠调度器。

  • 在一段时间内,多个进程都会通过切换交叉的方式,让多个进程在这段时间内得到推进,这种现象叫做并发。

操作系统,就是简单的根据队列进行先后调度吗?有没有可能突然来了一个优先级更高的进程?

  • 当代计算机,都符号抢占式内核。
  • 正在运行的低优先级进程,如果来了优先级更高的进程,调度器会直接把进程从CPU上剥离(无论低优先级的时间片是否跑完),给优先级高的进程,这就是抢占式内核。
2.5Linux维护进程的方式(O(1)调度)

依靠hash表和位图

task_struct* queue[140];
根据不同的优先级,将特点的进程放入相应的队列中。
比如优先级为2的进程,放入第二个task_struct queue中。

在这里插入图片描述

维护方式:

​ 当新增一个进程时(进程的优先级为n),将改进程放入queue[n]队列的末尾。这种方式也维护了进程的优先级,即高优先级的先运行。

进程切换

CPU内的寄存器,可以临时的存储数据

int hello()
{
    int a=10+20;
    return a;
}
int b=hello();
/*
	当返回值较小时
	a是临时变量,在返回时被销毁,系统会把a对应的值放入寄存器eax中;
	然后寄存器eax再将值mov给b对应的内存
*/

进程进行切换的时候,进程需要被CPU剥离。
在这里插入图片描述

  • 上下文数据保存在哪?
  • Linux的PCB,task_struct中有一个保存上下文数据的字段。

在这里插入图片描述

3.环境变量

3.1常见环境变量
PATH : 指定命令的搜索路径 [重点]
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)[重点]
SHELL : 当前Shell,它的值通常是/bin/bash

查看环境变量

env $NAME //NAME:你的环境变量名称
1. echo: 显示某个环境变量值[重点]
2. export: 设置一个新的环境变量[重点]
用法:export 本地变量名
3. env: 显示所有环境变量[重点]
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
3.2环境变量PATH

可执行程序的搜索路径是保存在一个全局变量中,PATH,给系统提高命令的搜索路径。是环境变量中的一个

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#每个目录中间使用冒号隔开。
#PATH的搜索顺序:从左向右依次进行程序的搜索,找到就执行程序,找不到就找下一个目录。如果全部都没有,就报错:command not found!
#也就是执行路径下的可执行文件可以直接使用(可以不指出相应的路径)

向PATH中添加路径

#方法一:
$ PATH="${PATH}:/root"
#在该用户下的环境变量中添加路径/root
#方法二:
$ export PATH=$PATH:/root
#在该用户下的PATH环境变量中添加路径/root

命令行变量

  • 普通变量
  • 环境变量(全局)
3.3环境变量的C/C++获取方式

main函数的参数

int main(int argc,char* argv[])
{
    /*
    argc:参数个数
    argv:指针数组,并且第一个字符串指向的是这个可执行程序的名字,最后一个字符串指向的是NULL 
    */
}
  • 给main函数传递的argc,char* argv[],传递的是命令行参数的个数和选项。
  • argv[]中第一个指向的是程序名,最后一个指向的是NULL。
  • main函数还可以传递第三个参数char env[ ]----->环境变量*

**实现命令行计算器 **

#include<string.h>
#include<stdio.h>
#include<unistd.h>

int main(int agrc,char* argv[])
{
    if(argc!=4)
    {
        printf("Useage:[-a][-s][-m][-d]\n");
    }
    int x=atoi(argv[1]);
    int y=atoi(argv[2]);
    if(strcmp("-a",argv[3])==0)
    {
        printf("%d-%d=%d\n",x,y,x-y);
    }
    else if(strcmp("-s",argv[3])==0)
    {
        printf("%d+%d=%d\n",x,y,x+y);
    }
    else if(strcmp("-m",argv[3])==0)
    {
        printf("%d*%d=%d\n",x,y,x*y);
    }
    else if(strcmp("-d",argv[3])==0)
    {
        printf("%d/%d=%d\n",x,y,x/y);
    }
    return 0;
}

在这里插入图片描述

获取环境变量
  • 通过main函数的第三个参数获取
遍历环境变量
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
	int i = 0;
	for(; env[i]; i++){
		printf("%s\n", env[i]);
	}
	return 0;
}

在这里插入图片描述

  • 通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
	extern char **environ;
	int i = 0;
	for(; environ[i]; i++){
		printf("%s\n", environ[i]);
	}
	return 0;
}
  • 系统调用:getenv(环境变量名)
#include<stdlib.h>
int main()
{
	printf("%s\n", getenv("PATH"));
	return 0;
}

实现一个只能被本用户调用的程序

int main()
{
    char * var=getenv("USER");
    if(strcasecmp(var,"west")!=0)
    {
        printf("没有权限...........\n");
    }
    else
    {
        printf("执行成功.........\n");
    }
    return 0;
}

一个函数声明的时候没有带参数,可以传参吗?

int fun()
{
	printf("hello world\n");    
}
int main()
{
    fun(10,20,30,40);
    return 0;
}

答案是可以传递参数。但是不能写成 fun(void),这就表明函数一定不能传递参数。

3.4本地变量和环境变量
  • 环境变量的全局性:环境变量会被子进程继承下去。
  • 本地变量:本质是在bash内部定义的变量,不会被子进程继承下去
  • **内建命令:**Linux下大部分命令都是通过创建子进程执行,但是有一部分特殊的命令,是在bash执行(调用bash内部的函数实现特点的功能)

在这里插入图片描述

4.进程地址空间

每一个进程启动,操作系统都会给进程创建一个地址空间,每一个进程都有自己的进程地址空间。

操作系统为了管理这些进程地址空间,有数据结构mm_struct进行管理【管理该进程的进程地址空间】。

image-20220813173812934

4.1进程的基本概念

进程的独立性:体现在进程相关的数据结构是独立的,代码和数据是独立的。

4.2MMU(内存管理单元)的作用

**在32位机器下,一个进程可以管理的虚拟内存空间大小为4G。**而实际上的物理空间大小不是4G。而物理内存和虚拟内存自己的对应和管理就是通过MMU和地址转换记录表进行。

image-20220705021709810

比如在.data中存放了a=10,那么就可以通过MMU(记录了虚拟内存和物理内存的映射关系),将他的虚拟地址转换为物理地址,从而访问内容10。

内存访问级别:

  • 0是最高的级别,内核访问的权限

  • 3是允许用户访问权限级别的权限

映射问题:

  • 用户空间映射到物理空间内存是独立的(不同的进程,即使虚拟地址相同,对应的也是不同的物理空间)

  • 内核空间映射到物理空间内存是相同的。(上图中,两个进程的kernal指向了同一块权限为0的MMU)

4.3页表

页表------将进程地址空间和物理地址映射【左边是虚拟地址,右边是物理地址】

  • 页表:也叫转换表(Translation Table).它负责MMU虚拟地址与物理地址之间的映射关系,由用户编写并存放在内存中。这样就可以将MMU与页表联系起来,进行转换工作了。页表由很多个页表项组成。

在这里插入图片描述

相对地址/逻辑地址/进程地址空间 --------> 映射物理地址

4.4读时共享写时拷贝原则
int val=100;
int main()
{
    pid_t pid=fork();
    if(pid==0)
    {
        int i=5;
        while(i)
        {
            printf("I am father pro,pid=%d,val=%d",getpid(),val);
            sleep(1);
            i--;
        }
        val=200;
        printf("begin chage................\n");
        while(1)
        {
            printf("I am child pro=%d,val=%d\n",getpid(),val);
            sleep(1);
        }
    }
    else
    {
      while(1)
      {
          printf("I am father pro,pid=%d,val=%d\n",getpid(),val);
          sleep(1);
      }
    }
   return 0;
}

在这里插入图片描述

为什么进程地址一样,但是内容确不一样。

写时拷贝原则:

image-20220813172853055

实现了进程的独立性

为什么fork()有两个返回值?

pid_t pid是属于父进程空间定义的变量,return返回的时候,pid发生了写时拷贝,所以有两个返回值。

4.5为什么有进程地址空间
  • 指针越界的问题,保护内存安全
  • 进行内存管理,提高运行效率。
  • 对功能模块进行解耦

在这里插入图片描述

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

【Linux】进程基础 的相关文章

  • Linux C++ 错误:未定义对“dlopen”的引用

    我在 Linux 上使用 C Eclipse 工作 并且想要使用一个库 Eclipse 向我显示一个错误 undefined reference to dlopen 你知道解决办法吗 这是我的代码 include
  • Xvfb 冻结初始化 GLX 扩展

    我正在尝试运行无头 Xvfb 服务器来捕获 Amazon EC2 micro 上的屏幕截图 但它在 GLX 上陷入了困境 我使用此脚本安装了 GLX Xvfb 和所有库 https gist github com joekiller 414
  • 找出Linux上一个进程使用了​​多少内存页

    我需要找出进程分配了多少内存页 每个页面是 4096 进程内存使用情况我在查找正确值时遇到一些问题 当我查看 gome system monitor 时 内存映射下有几个值可供选择 Thanks 这样做的目的是将内存使用量除以页数并验证页大
  • Pthreads - 高内存使用率

    我正在用 C 编写一些东西 在 256Mb 系统上的 Linux 中创建大量 Pthread 我通常有 200Mb 的免费空间 当我使用少量线程运行该程序时 它可以工作 但是一旦我让它创建大约 100 个线程 它就会出现错误 因为系统内存不
  • 如何在 Vim 中突出显示 Bash 脚本?

    我的 Vim 编辑器自动突出显示 PHP 文件 vim file php HTML 文件 vim file html 等等 但是当我输入 vim file在里面写一个Bash脚本 它不会突出显示它 我如何告诉 Vim 将其突出显示为 Bas
  • Apache 端口转发 80 到 8080 并访问 Apache (80) 中托管的应用程序,即 phpMyadmin 和 Tomcat (8080)

    我想访问托管在 tomcat 服务器 8080 中的应用程序 myapp 当前可以通过以下方式访问http example com 8080 myapp http example com 8080 myapp in http example
  • 选择fasta文件中氨基酸超过300个且“C”出现至少4次的序列

    我有一个包含蛋白质序列的 fasta 文件 我想选择超过 300 个氨基酸且半胱氨酸 C 氨基酸出现超过 4 次的序列 我使用此命令来选择具有超过 300 个 aa 的序列 cat 72hDOWN fasta fasta bioawk c
  • 我想在 Red Hat Linux 服务器中执行 .ps1 powershell 脚本

    我有一个在窗口中执行的 ps1 powershell 脚本 但我的整个数据都在 Linux 服务器中 有什么可能的方法可以让我在红帽服务器中执行 powershell 脚本 powershell脚本是 Clear Host path D D
  • Linux中如何避免sleep调用因信号而中断?

    我在 Linux 中使用实时信号来通知串行端口中新数据的到达 不幸的是 这会导致睡眠呼叫在有信号时被中断 有人知道避免这种行为的方法吗 我尝试使用常规信号 SIGUSR1 但我不断得到相同的行为 来自 nanosleep 联机帮助页 nan
  • 更新Linux中的包含路径

    我的 my path to file 文件夹中有几个头文件 我知道如何将这些文件包含在新的 C 程序中 但每次我都需要在包含它之前输入头文件的完整路径 我可以在linux中设置一些路径变量 以便它自动查找头文件吗 您可以创建一个 makef
  • Linux shell 从用户输入中获取设备 ID

    我正在为一个程序编写安装脚本 该程序需要在其配置中使用 lsusb 的设备 ID 因此我正在考虑执行以下操作 usblist lsusb put the list into a array for each line use the arr
  • BASH:输入期间按 Ctrl+C 会中断当前终端

    我的 Bash 版本是 GNU bash version 4 3 11 1 release x86 64 pc linux gnu 我有一段这样的代码 while true do echo n Set password read s pas
  • Linux无法删除文件

    当我找到文件时 我在删除它们时遇到问题 任务 必须找到带有空格的文件并将其删除 我的尝试 rm find L root grep i 但我有错误 rm cannot remove root test No such file or dire
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li
  • 如何才能将 TCP 连接返回到同一端口?

    机器是 RHEL 5 3 内核 2 6 18 有时我在 netstat 中注意到我的应用程序有连接 建立了 TCP 连接本地地址 and 国外地址是一样的 其他人也报告了同样的问题 症状与链接中描述的相同 客户端连接到本地运行的服务器的端口
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu

随机推荐

  • BigDecimal保留两位小数

    天行健 君子以自强不息 地势坤 君子以厚德载物 每个人都有惰性 但不断学习是好好生活的根本 共勉 文章均为学习整理笔记 分享记录为主 如有错误请指正 共同学习进步 BigDecimal保留两位小数 保留两位小数 1 setScale 2 D
  • vue脚手架-上传图片 编辑修改图片(三)

    需求 点击编辑图案的时候 需要弹出框 里面除了能修改图片信息之外 还得能够更换图片 此篇文章主要讲述如何更换图片 因为时更改单张图片的 所以特别想更换头像 有没有 因此我使用了element ui中的更换头像的插件来写的 H5中更换图片的部
  • Flutter 完整示例

    经过这一段对 Flutter 的了解和接触 掌握如何完整使用 Flutter 开发一个项目 实际上 在 Flutter 中 一切皆 widget 我们的界面都是由各种 widget 堆叠出来的 一个 Flutter 工程涉及以下几个要点 工
  • WINDOWS窗体应用程序与WPF应用程序的区别?

    WINDOWS窗体应用程序与WPF应用程序的区别 用WPF更容易做的漂亮 感觉有以下几个大区别 WPF的线程模型和winform的线程模型不同 WPF到处用到数据绑定 winform在列表中才用的多 WPF支持3D winform本身没有
  • Ubuntu20.04安装NVIDIA混合精度计算库apex全流程及各类报错问题解答

    目录 一 安装CUDA 二 安装apex 三 各类报错问题解决 3 1 C 编译错误 3 2 Apex优化算子错误 3 3 CUDA错误 3 4 g 或gcc错误 背景 跟李沐老师一起探索RTX 3090的深度学习浮点运算性能 需要安装ap
  • 登录界面BootStramp模板

    一 效果图 二 代码部分
  • CPU内存磁盘IO过高问题处理

    CPU占用过高分析 可以用top命令查看哪一个进程占用cpu高 或者哪一个占用内存大 top 13 55 32 up 59 days 19 18 2 users load average 0 00 0 04 0 09 Tasks 161 t
  • 获取一周登陆3次以上的用户数,mysql

    select count 1 from select userId count distinct date format createTime Y m d from session user where date format create
  • PLSQL Developer连接远程数据库方式

    作者 Frank bettterMan 来源 CSDN 原文地址 https blog csdn net xintonghanchuang article details 60869189 1 直接通过IP连接 1 输入对应数据库用户名与密
  • 使用gradle创建 Java 工程

    如果显示连接超时 换网 不要用校园网 1 随便目录 在用cmd呼出终端 2 在终端输入gradle init 初始化 gradle init 2是项目 依稀记得 1是2的简化版 这里选2 我学的是java 所以3 这里选语言 三个默认 这里
  • OpenStack架构详解

    1 OpenStack概述 OpenStack既是一个社区 也是一个项目和一个开源软件 它提供了一个部署云的操作平台或工具集 其宗旨在于 帮助组织运行为虚拟计算或存储服务的云 为公有云 私有云 也为大云 小云提供可扩展的 灵活的云计算 Op
  • 【第四章】详解Feign的实现原理

    1 1 Feign概述 这篇文章主要讲述如何通过Feign去消费服务 以及Feign的实现原理的解析 Feign是Netflix开发的声明式 模板化的HTTP客户端 Feign可以帮助我们更快捷 优雅地调用HTTP API Feign是个H
  • VitePress开发记录(二)之LaTeX语法支持

    前言 当我在我的博客网站更新我的吴恩达机器学习笔记时 出现了一个情况 VitePress默认的markdown it解析器似乎无法渲染LaTeX数学公式 于是我去VitePress官方中查看issue是否有解决的方案 官方给出的解答是 这里
  • 华为OD机试真题-模拟商场优惠打折【2023Q1】

    题目内容 模拟商场优惠打折 有三种优惠券可以用 满减券 打折券和无门槛券 满减券 满100减10 满200减20 满300减30 满400减40 以此类推不限制使用 打折券 固定折扣92折 且打折之后向下取整 每次购物只能用1次 无门槛券
  • SpringBatch文章系列-SPL表达式的使用

    参考例子
  • 爬虫如何快速定位到加密入口

    这里有多种定位加密入口方法 通过打全局xhr断点找到加密入口 可以将在 处点击添加xhr断点 可以针对某个值进行打xhr断点 直接通过关键字找到加密入口 在前面文章讲述过https blog csdn net zhp980121 artic
  • Springboot+vue 社团管理系统(前后端分离)

    Springboot vue 社团管理系统 前后端分离 zero 项目功能设计图 一 数据库设计 项目准备 1 建表 2 表目录 二 前端编写 vue 1 搭建Vue框架 2 放入静态资源 assets文件包括static文件的静态文件 3
  • 2017 年提高组初赛

    第 6 题 1 5 分 若某算法的计算时间表示为递推关系式 T N 2 T N 2 N l o g N T N 2T N 2 NlogN T N 2T N 2 NlogN T N 2 2 T N 4 N 2 l o g N 2 2 T N
  • TencentOS-tiny 内存管理(十 二)- 动态内存

    一 内存管理 动态内存 概述 动态内存管理模块 提供了一套动态管理系统内存的机制 支持用户动态的申请 释放不定长内存块 API讲解 编程实例 1 在tos config h中 配置动态内存组件开关TOS CFG MMHEAP EN defi
  • 【Linux】进程基础

    文章目录 1 冯诺依曼体系 1 2操作系统 2 进程 2 1进程的概念 2 2 task struct 2 3进程的状态 2 4进程优先级 优先级VS权限 为何会存在优先级 Linux下的优先级相关概念 2 5其他重要概念 单道和多道程序设