lv5 嵌入式开发-1 进程的创建和回收

news2024/7/6 20:07:13

目录

1 进程概念

2 进程内容

3 进程类型

4 进程状态

5 查看进程信息

5.1 相关命令ps top /proc

5.2 相关命令 nice renice 

5.3 相关命令job bg fg 

6 子进程概念

7 子进程创建 – fork

8 父子进程

9 思考

10 进程结束 – exit/_exit

11 进程的回收

11.1 进程回收 – wait

11.2 进程回收 – waitpid


掌握:进程概念、进程包含内容、进制状态、查看进程信息、前后台进程切换、改变进行优先级、创建子进程、父子进程、结束进程

1 进程概念

程序

  • 存放在磁盘上的指令和数据的有序集合(文件)
  • 静态的

进程

  • 执行一个程序所分配的资源的总称
  • 进程是程序的一次执行过程
  • 动态的,包括创建、调度、执行和消亡

2 进程内容

  • BSS段:BSS段通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。 
  • 数据段:数据段通常是指用来存放程序中已初始化的全局变量的一块内存区域
  • 代码段:代码段通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等
  • 堆(heap):堆是用于存放进程运行中被动态分配的内存段,当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
  • 栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进后出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
  • 进程控制块(pcb) :进程标识PID 、进程用户 、进程状态、优先级 、文件描述符表

进程放在RAM种,程序放在ROM中(单片机就在flash中)

3 进程类型

  • 交互进程:在shell下启动。以在前台运行,也可以在后台运行 (前台 ./test)
  • 批处理进程:和在终端无关,被提交到一个作业队列中以便顺序执行
  • 守护进程:和终端无关,一直在后台运行

4 进程状态

运行态:进程正在运行,或者准备运行

等待态:进程在等待一个事件的发生或某种系统资源 (分为可中断和不可中断)

停止态:进程被中止,收到信号后可继续运行

死亡态:已终止的进程,但pcb没有被释放(僵尸态)

5 查看进程信息

5.1 相关命令ps top /proc

ps     查看系统进程快照
top    查看进程动态信息
/proc  查看进程详细信息
ps 命令详细参数:
-e:显示所有进程
-l:长格式显示更加详细的信息
-f 全部列出,通常和其他选项联用

表头

含义

F

进程标志,说明进程的权限,常见的标志有两个:

  • 1:进程可以被复制,但是不能被执行;
  • 4:进程使用超级用户权限;

S

进程状态。进程状态。常见的状态有以下几种:

  1. -D:不可被唤醒的睡眠状态,通常用于 I/O 情况。
  2. -R:该进程正在运行。
  3. -S:该进程处于睡眠状态,可被唤醒。
  4. -T:停止状态,可能是在后台暂停或进程处于除错状态。
  5. -W:内存交互状态(从 2.6 内核开始无效)。
  6. -X:死掉的进程(应该不会出现)。
  7. -Z:僵尸进程。进程已经中止,但是部分程序还在内存当中。
  8. -<:高优先级(以下状态在 BSD 格式中出现)。
  9. -N:低优先级。
  10. -L:被锁入内存。
  11. -s:包含子进程。
  12. -l:多线程(小写 L)。
  13. -+:位于后台。

UID

运行此进程的用户的 ID;

PID

进程的 ID;

PPID

父进程的 ID;

C

该进程的 CPU 使用率,单位是百分比;

PRI

进程的优先级,数值越小,该进程的优先级越高,越早被 CPU 执行;

NI

进程的优先级,数值越小,该进程越早被执行;

ADDR

该进程在内存的哪个位置;

SZ

该进程占用多大内存;

WCHAN

该进程是否运行。"-"代表正在运行;

TTY

该进程由哪个终端产生;

TIME

该进程占用 CPU 的运算时间,注意不是系统时间;

CMD

产生此进程的命令名;

top    查看进程动态信息

shift +> 后翻页

ps -elf|grep watchdog

shift +< 前翻页

top -p PID  查看某个进程

示例:

ps -elf|grep watchdog
//列出所有进程,找到字符串有watchdog的进程

示例:

ls /proc/

/proc 是一个虚拟文件系统,提供了关于运行中进程和系统内核状态的信息。 

 数字代表某个进程目录

ls /proc/数字

5.2 相关命令 nice renice 

nice   按用户指定的优先级运行进程

nice [-n NI值] 命令
NI 范围是 -20~19。数值越大优先级越低
普通用户调整 NI 值的范围是 0~19,而且只能调整自己的进程。
普通用户只能调高 NI 值,而不能降低。如原本 NI 值为 0,则只能调整为大于 0。
只有 root 用户才能设定进程 NI 值为负值,而且可以调整任何用户的进程。

renice   改变正在运行进程的优先级

renice [优先级] PID

示例: 

nice -n 10 command     //将启动一个新的 shell 进程,并将它的优先级设置为 10。
renice -n 5 -p 1234    //将把进程 ID 为 1234 的进程的优先级设置为 5。

5.3 相关命令job bg fg 

示例:

创建一个循环程序,编译执行

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

int main(int argc, char * argv[])
{
	while(1)
	{
		sleep(1);
	}
	return 0;
}

后台运行两种方式: 

  • 此时控制台输出,在 Linux 控制端,按下 CTRL+Z 的组合键可以将当前正在运行的前台进程挂起,并放入后台,同时返回一个进程挂起的提示信息。这个被挂起的进程会停止执行,但它的状态不会被清除,直到被唤醒或终止。
  • ./a.out &  把test程序后台运行

此时查看进程状态,可以发现状态为T,代表停止。

linux@linux:~/Desktop$ ps -elf|grep a.out
0 T linux     2869  2784  0  80   0 -   506 signal 09:46 pts/1    00:00:00 ./a.out
0 S linux     3226  2784  0  80   0 -  1171 pipe_w 10:18 pts/1    00:00:00 grep --color=auto a.out


//T代表已经a.out程序已经停止
jobs   查看后台进程
bg     将挂起的进程在后台运行
fg      把后台运行的进程放到前台运行,接序号

示例: 

linux@linux:~/Desktop$ jobs
[1]+  Stopped                 ./a.out
linux@linux:~/Desktop$ fg 1
./a.out


linux@linux:~/Desktop$ bg 1
[1]+ ./a.out &
linux@linux:~/Desktop$ ps -elf|grep a.out
0 S linux     2869  2784  0  80   0 -   506 hrtime 09:46 pts/1    00:00:00 ./a.out
0 S linux     3329  2784  0  80   0 -  1171 pipe_w 10:32 pts/1    00:00:00 grep --color=auto a.out
linux@linux:~/Desktop$ jobs
[1]+  Running                 ./a.out &

6 子进程概念

子进程为由另外一个进程(对应称之为父进程)所创建的进程

除了系统启动时的第一个进程(通常是 init 或 systemd或0号进程)外,所有其他进程都是由父进程创建的。这种父子进程的关系形成了一个进程树或进程层级结构。

7 子进程创建 – fork

#include  <unistd.h>
pid_t  fork(void);
  • 创建新的进程,失败时返回-1
  • 成功时父进程返回子进程的进程号,子进程返回0
  • 通过fork的返回值区分父进程和子进程

示例:

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

int main(int argc,char **argv)
{
	pid_t pid;
	printf("before fork\n");
	pid = fork();
	printf("after fork\n");
	printf("pid=%d\n",(int)pid);

}


linux@linux:~/Desktop$ ./a.out 
before fork
after fork
pid=3607                //父打印子进程号
linux@linux:~/Desktop$ 
after fork
pid=0                   //子进程打印0

注意:

1 子进程只执行fork之后的代码

2.父子进程执行顺序是操作系统决定的。

如果需要控制谁先执行,需要加一些延时 

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

int main(int argc,char **argv){
    
    pid_t pid;
    printf("before fork\n");
    pid = fork();
    if(pid>0){
       printf("This is father process\n");
       printf("pid=%d\n",(int)pid);
       printf("father after fork\n");
   }else if(pid==0){
       printf("This is child process\n");
       printf("pid=%d\n",(int)pid);
       printf("child after fork\n");
    }else if(pid<0){
       perror("fork");
       return 0;
    }
   // printf("pid=%d\n",(int)pid);
  //  printf("after fork\n");
  

}

8 父子进程

子进程继承了父进程的内容(从fork以后执行)

父子进程有独立的地址空间,互不影响

若父进程先结束 : 

        -子进程成为孤儿进程,被init进程收养  

        -子进程变成后台进程

若子进程先结束:

       - 父进程如果没有及时回收,子进程变成僵尸进程

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

int main(int argc,char **argv){
    
    pid_t pid;
    printf("before fork\n");
    pid = fork();
    if(pid>0){
       printf("This is father process\n");
       printf("pid=%d\n",(int)pid);
       printf("father after fork\n");
       while(1){
         sleep(1);
         printf("father sleep\n");
       }
   }else if(pid==0){
       printf("This is child process\n");
       printf("pid=%d\n",(int)pid);
       printf("child after fork\n");
       while(1){
          sleep(1);
          printf("child sleep\n");
       }
    }else if(pid<0){
       perror("fork");
       return 0;
    }
   // printf("pid=%d\n",(int)pid);
  //  printf("after fork\n");
  

}

 

kill -9 分别演示父进程和子进程先结束的状态。 

 1代表子进程被init收养了

 0代表僵尸进程

9 思考

子进程从何处开始运行?

答:子进程从fork()函数的调用处开始运行。

父子进程谁先执行?

答:父子进程的执行顺序是不确定的,取决于操作系统的调度算法。在一般情况下,父进程和子进程是并发执行的,可能会交替执行,也可能先执行父进程再执行子进程。

父进程能否多次调用fork? 子进程呢?

答:父进程可以多次调用fork()函数创建多个子进程。每次调用fork()函数都会返回两次,在父进程中返回子进程的进程ID(PID),在子进程中返回0。这样可以通过判断返回值来区分父进程和子进程,并根据需要执行不同的代码逻辑。

子进程也可以调用fork()函数创建自己的子进程,从而形成进程的层次结构,但需要注意,子进程创建的子进程与原始父进程无关。

示例:是否创建了5个进程?

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

int main(){
    pid_t pid;
    int i;    
    for(i=0;i<5;i++){
        pid = fork();
        if(pid<0){
            perror("fork");
            return 0;
        }else if(pid==0){
            printf("child process\n");
            sleep(5);
        }else{
            printf("Father process\n");
            sleep(5);
        }
    }

    sleep(100);


}

实际子进程在fork,父进程也在fork 

 

示例:只让父进程fork

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

int main(){
    pid_t pid;
    int i;    
    for(i=0;i<5;i++){
        pid = fork();
        if(pid<0){
            perror("fork");
            return 0;
        }else if(pid==0){
            printf("child process\n");
            sleep(5);
            break;
        }else{
            printf("Father process\n");
            sleep(5);
        }
    }

    sleep(100);


}

 

 

示例:只让子进程fork

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

int main(){
    pid_t pid;
    int i;    
    for(i=0;i<5;i++){
        pid = fork();
        if(pid<0){
            perror("fork");
            return 0;
        }else if(pid==0){
            printf("child process\n");
            sleep(5);
        }else{
            printf("Father process\n");
            sleep(5);
            break;
        }
    }

    sleep(100);


}

 

10 进程结束 – exit/_exit

#include <stdlib.h> 
#include  <unistd.h>
void  exit(int  status);
void  _exit(int  status);
void  _Exit(int  status); //与小写一样

结束当前的进程并将status返回

exit结束进程时会刷新(流)缓冲区(区别)

示例1:

主函数(main函数)在结束时默认会调用exit()函数。exit()函数用于正常终止程序,并返回一个退出状态给操作系统。不当主函数执行完毕或遇到return语句时,会自动隐式地调用exit()函数。这会导致程序退出,并将返回值作为退出状态码传递给操作系统。

#include <stdio.h>
#include <stdlib.h>  //exit 和_exit引用不一样

int main(void) {
    printf(“this process will exit”);
    exit(0);
    printf(“never  be  displayed”);  //不打印
}


$ ./a.out  
this process will be exit   //加不加exit始终会打印

 

示例2:

#include <stdio.h>
#include <stdlib.h>
  
int main(void) {
    printf(“using exit…\n”);
    printf(“This is the end”);
    exit(0);
}

$ ./a.out  
using exit…
This is the end

示例3:不刷新缓存区的_exit()

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

int main(int argc,char**argv){

   printf("hello world");   //不打印
   _exit(0);
   printf("after exit");    //不打印
   return 0;
}


//什么都不打印

11 进程的回收

子进程结束时由父进程回收

孤儿进程由init进程回收

若没有及时回收会出现僵尸进程

11.1 进程回收 – wait

#include <sys/wait.h>

pid_t wait(int *status); 
  • 成功时返回回收的子进程的进程号;失败时返回EOF
  • 若子进程没有结束,父进程一直阻塞
  • 若有多个子进程,哪个先结束就先回收
  • status 指定保存子进程返回值和结束方式的地址
  • status为NULL表示直接释放子进程PCB,不接收返回值

示例:

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char** argv){

   pid_t pid;
   pid_t rpid;
   pid = fork();
   int status;
   if(pid<0){
      perror("fork");
      return 0;
   }
   else if(pid == 0){
       sleep(10);
       printf("child will exit\n");
       exit(2);

   }else if(pid >0){
       rpid = wait(&status);
       printf("Get child status=%x\n",WEXITSTATUS(status));
   }

}

 返回值是多个内容组成的标志位,需要调用宏定义打印返回值

 

查看是否有僵尸进程 

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char** argv){

   pid_t pid;
   pid_t rpid;
   pid = fork();
   int status;
   if(pid<0){
      perror("fork");
      return 0;
   }
   else if(pid == 0){
       sleep(10);
       printf("child will exit\n");
       exit(2);

   }else if(pid >0){
       rpid = wait(&status);
       sleep(20);
       printf("Get child status=%x\n",WEXITSTATUS(status));
   }

   while(1){
     sleep(1);
   }

}

 如果去除wait,产生了僵尸进程

进程返回值和结束方式

子进程通过exit / _exit / return 返回某个值(0-255)

父进程调用wait(&status) 回收

  • WIFEXITED(status)       判断子进程是否正常结束
  • WEXITSTATUS(status)  获取子进程返回值
  • WIFSIGNALED(status)  判断子进程是否被信号结束
  • WTERMSIG(status)       获取结束子进程的信号类型

11.2 进程回收 – waitpid

#include  <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int option);
  • 成功时返回回收的子进程的pid或0;失败时返回EOF  
  • pid可用于指定回收哪个子进程或任意子进程  
  • status指定用于保存子进程返回值和结束方式的地址  
  • option指定回收方式,0 或 WNOHANG

参数:

pid

  • pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
  • pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
  • pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
  • pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options

options提了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用 

WNOHANG :若由pid指定的子进程未发生状态改变(没有结束),则waitpid()不阻塞,立即返回0

WUNTRACED: 返回终止子进程信息和因信号停止的子进程信息

 wait(wait_stat) 等价于waitpid(-1,wait_stat,0) 

示例:

waitpid(pid, &status, 0);

waitpid(pid, &status, WNOHANG);

waitpid(-1, &status, 0);

waitpid(-1, &status, WNOHANG);
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char** argv){

   pid_t pid;
   pid_t rpid;
   pid = fork();
   int status;
   if(pid<0){
      perror("fork");
      return 0;
   }
   else if(pid == 0){
       sleep(10);
       printf("child will exit\n");
       exit(2);

   }else if(pid >0){
       rpid = wait(&status);
       sleep(20);
       //waitpid(-1,&status,WNOHANG);  //只有一个进程,-1和参数pid效果一样
       waitpid(pid,&status,0);
       printf("Get child status=%x\n",WEXITSTATUS(status));
   }

   while(1){
     sleep(1);
   }

}

 

示例2

waitpid早就执行了,但是exit还会执行,注意这种情况可以考虑waitpid前也加延时函数,晚于exit用于进程回收

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018746.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

opencv形状目标检测

1.圆形检测 OpenCV图像处理中“找圆技术”的使用-图像处理-双翌视觉OpenCV图像处理中“找圆技术”的使用,图像处理,双翌视觉https://www.shuangyi-tech.com/news_224.htmlopencv 找圆心得&#xff0c;模板匹配比霍夫圆心好用 - 知乎1 相比较霍夫找直线算法&#xff0c; 霍夫找…

RK3568平台开发系列讲解(调试篇)系统运行相关频率设置

🚀返回专栏总目录 文章目录 一、CPU 频率设置二、DDR 频率设置三、NPU 频率设置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 CPU 默认是 interactive 状态,它会根据 CPU 使用率和目标负载来动态地调整 CPU 频率。为获得更高运行速度或者性能评估,我们需要手动固…

红外成像技术

针对GI S设备红外检测目前未被大众认可的原因&#xff1a; 1 、 目前对GI S带电检测的意义认识不够&#xff0c; 许多单位认为GI S测温发现不了什么&#xff0c; 对其测温仅仅检测接头。 2、 GI S外壳温度异常的原因多种&#xff0c; 出现外壳温度异常大家不会分析&#xff0c;…

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格&#xff1f; 在添加参数到 StringBuffer 时&#xff0c;你可以在每次添加参数之后都添加一个空格&#xff0c;如下所示&#xff1a; StringBuffer stringBu…

【Linux入门】---Linux权限管理详解

文章目录 1.shell命令以及运行原理2.linux用户分类su指令切换用户 3.Linux权限管理3.1Linux文件访问者3.2文件类型和访问权限3.3文件权限值的表示方法3.4文件访问权限的相关设置方法chmod指令--权限修改方法①chmod指令--权限修改方法②chown指令chgrp指令umask指令file指令 4.…

按键点亮led灯

原理图: K0这个按键按下时&#xff0c;开发板D1这个灯亮&#xff0c;松开&#xff0c;灯灭 代码如下: #include "stm32f4xx.h" void LED_Init(void) {//1.定义一个GPIO外设的结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//RCC_AHB1PeriphClockCmd(RCC_AHB1Pe…

【自学开发之旅】Flask-前后端联调-异常标准化返回(六)

注册联调&#xff1a; 前端修改&#xff1a; 1.修改请求向后端的url地址 文件&#xff1a;env.development修改成VITE_API_TARGET_URL http://127.0.0.1:9000/v1 登录&#xff1a;token验证 校验forms/user.py from werkzeug.security import check_password_hash# 登录校验…

目标检测前言,RCNN,Fast RCNN,Faster RCNN

一、RCNN&#xff1a; 找到概率最高的目标之后&#xff0c;与其他目标进行IOU交并比计算&#xff0c;若高于一定值&#xff0c;则说明这两张图片预测的是同一个目标&#xff0c;则把概率低的目标删掉 二、Fast RCNN 因为是直接得到特征图之后进行映射&#xff0c;所以不限制输入…

AXMB-GY v2.0: 全新开源的爱希彩虹易支付模板,简洁轻量级设计

AXMB-GYv2.0&#xff1a;全新发布的开源爱希彩虹易支付模板。该模板对用户中心、登录、注册、找回密码和支付页面进行了美化&#xff0c;采用了简洁轻量级的设计风格。作为全开源模板&#xff0c;它提供了灵活且自由的定制和二次开发选项。同时&#xff0c;该模板具有出色的兼容…

Typora偏好设置中图床的配置文件点击打开没有反应

Typora偏好设置中图床的配置文件点击打开没有反应 突然发现Typora偏好设置中图床打开配置文件点击没有反应&#xff0c;如下按钮所示 可能是因为系统不知道用什么软件打开json&#xff0c;直接进入配置文件json目录&#xff0c;一般位置在C:\Users\<your_user_name>\.pi…

CSS选择器笔记

A plate #id #fancy A B plate apple #id A #fancy pickle .classname .small A.className orange.small #id.className #big.wide A,B both plate,bento * all A * plate * AB 紧跟在盘子后的苹果 plate apple A~B 跟在盘子后面所有的泡菜 plate~b…

Mybatis学习笔记5 面向接口CRUD练习

新建项目 大致目录结构 核心配置文件 日志配置文件,只需要引入logback依赖 配置文件名为logback.xml即可 <?xml version"1.0" encoding"UTF-8"?> <configuration debug"false"><!--定义⽇志⽂件的存储地址--><propert…

8.全配置自动生成模块前后端

文章目录 学习资料配置式开发全新的模块&#xff08;快速实现&#xff09;字典管理代码生成器详细属性设置全智能模块开发查询调整-多表连接药品模块-生产厂家下拉框 学习资料 https://www.bilibili.com/video/BV13g411Y7GS/?p19&spm_id_frompageDriver&vd_sourceed0…

Qt ffmpeg音视频转换工具

Qt ffmpeg音视频转换工具&#xff0c;QProcess方式调用ffmpeg&#xff0c;对音视频文件进行格式转换&#xff0c;支持常见的音视频格式&#xff0c;主要在于QProcess的输出处理以及转换的文件名和后缀的处理&#xff0c;可以进一步加上音视频剪切合并和音视频文件属性查询修改的…

GraphQL基础知识与Spring for GraphQL使用教程

文章目录 1、数据类型1.1、标量类型1.2. 高级数据类型 基本操作2、Spring for GraphQL实例2.1、项目目录2.2、数据库表2.3、GraphQL的schema.graphql2.4、Java代码 3、运行效果3.1、添加用户3.2、添加日志3.3、查询所有日志3.4、查询指定用户日志3.5、数据订阅 4、总结 GraphQL…

多输入多输出 | Matlab实现GWO-BP灰狼算法优化BP神经网络多输入多输出预测

多输入多输出 | Matlab实现GWO-BP灰狼算法优化BP神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现GWO-BP灰狼算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现GWO-BP灰狼算法优化BP神经网络…

python有限差分法求解一维热传导方程

​1、方程及其离散 1.1一维热传导方程 1.2离散化 设定步长&#xff0c;依据上述方程得到递推关系&#xff1a; 2、python求解实现 import numpy as np import matplotlib.pyplot as plth 0.1#空间步长 N 30#空间步数 dt 0.0001#时间步长 M 10000#时间的步数 A dt/(h**2)…

Oracle数据库体系结构(一)_概述

目录 1 Oracle系统框架 1.1 Orace SGA组成 1.2 Oracle后台进程 1.3 PGA服务进程 2 数据库与实例 2.1 数据库 2.2 实例 3 总结 Oracle公司&#xff08;甲骨文&#xff09;是全球最大的信息管理软件及服务供应商&#xff0c;成立于1977年&#xff0c;总部位于美国加…

关于rdkit 错误2w08_ligand: warning - O.co2 with non C.2 or S.o2 neighbor.

1 问题&#xff1a; 读取 PDBBindv2019的数据集&#xff0c;尝试把所有配体的mol2文件转换成对应smiles表达式。大约超过1千个出现问题。 主要问题就是‘warning - O.co2 with non C.2 or S.o2 neighbor’。 2 原因&#xff1a; Phosphate group - warning O.co2 with non C…

Rocky Linux 安装图解(替代centos)服务器+桌面

centos自从20年底转变为不稳定版本后&#xff0c;有很多替代方案 经过近3年的发展&#xff0c;rocky linux算是一个比较好的选择&#xff0c;一是依照red hat企业版来做&#xff0c;二是rocky的发起者也是centos的创始人 如果想安装debian&#xff0c;可以参考&#xff1a;deb…