[Linux]进程概念以及进程状态

news2024/12/26 2:26:41

🥁作者华丞臧.
📕​​​​专栏:【LINUX】
各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞+收藏+关注)。如果有错误的地方,欢迎在评论区指出。
推荐一款刷题网站 👉 LeetCode刷题网站


文章目录

  • 前言
  • 一、什么是进程
    • 1.1 基本概念
    • 1.2 如何描述进程
    • 1.3 组织进程
    • 1.4 查看进程
    • 1.5 通过系统调用获取进程标识符
    • 1.6 fork初识-通过系统调用创建进程
  • 二、进程状态
    • 2.1 Linux内核源代码
    • 2.2 僵尸进程-Z(zombie)
      • 2.2.1 僵尸进程概念
      • 2.2.2 **模拟僵尸进程**
      • 2.2.2 僵尸进程危害
    • 2.3 孤儿进程
      • 2.3.1 孤儿进程概念
      • 2.3.1 模拟孤儿进程
  • 补充


前言

通过前面对操作系统的学习,我们知道操作系统有四大基本的功能,分别是文件管理、进程管理、驱动管理、内存管理;操作系统进行管理的本质是:先描述,在组织,那么对于进程来说也是如此,本文针对进程管理,主要讲述进程的概念、操作系统如何描述进程以及一些进程的相关操作。

一、什么是进程

1.1 基本概念

课本概念:程序的一个执行实例,正在执行的程序等。
内核概念:担当分配系统资源(CPU时间,内存)的实体。

通俗地讲,进程就是一个运行起来(加载到内存)的程序,因此进程具有动态属性;进程和程序是不一样的,程序的本质是存放在磁盘上的文件

1.2 如何描述进程

人们通过属性认识世界。一个事物一定具有某些特定的属性,人们通过描述事物的属性来认识事物,比如网购一台电脑,商家为了让买家更加了解电脑的性能,通常会把电脑的各个硬件和电脑上的操作系统显示给买家,买家通过这些属性来认识这台电脑并且分辨其性能。
在这里插入图片描述
当需要管理某一类事物时,就可以用其单个对象主要的属性来描述这一类的事物,然后将其组织起来管理。在操作系统上,只要是进程就一定具有相似的属性,因此将这些属性抽象描述起来,再使用特定的数据结构将其组织起来,操作系统就能很好的对进程进行管理了。

C语言当中定义自定义类型有struct关键字,在C++中对struct进行了升级变成了类,同样可以用来定义一个自定义类型。

Linux底层是使用C语言完成的,因此Linux中描述进程使用的是struct,而描述进程的结构体称为PCB(又称进程控制块)。

  • 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
  • 课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct

task_struct PCB的一种

  • 在Linux中描述进程的结构体叫做task_struct。
  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

task_ struct内容分类

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

1.3 组织进程

在Linux内核源代码里可以找到组成进程的方法。所有运行在系统里的进程都已task_struct链表的形式存在内核里。

因此操作系统所谓的对进程进行管理,就转换成对进程对应的PCB进行相关的管理,即对链表的增删查改。

//先描述,再组织的工作如下
struct task_struct 内核结构体 -> 内核对象task_struct —> 将该结构与对应代码和数据关联起来 

//进程控制块
struct task_struct
{
	//该进程的所有属性
	//该进程对应的代码和属性地址
	struct task_struct *next;
}

进程 = 内核数据结构(task_struct) + 进程对应的磁盘代码
在这里插入图片描述

为什么会有PCB(struct task_struct)结构体呢?

因此操作系统管理进程需要先描述再组织,而struct task_struct就是Linux为了·描述进程而设计的结构体。

1.4 查看进程

进程的信息可以通过 /proc 系统文件夹查看,在根目录下有很多路径,如下图:
在这里插入图片描述

可以看到有一个proc路径,proc是Linux系统上的内存文件系统,在proc当中存储着当前系统实时的进程信息。
在这里插入图片描述

在运行test程序,获取该进程的pid,再去查看proc路径下的pid,发现proc目录存在一个pid命名的的目录,结束进程发现该目录不存在。(程序每一次运行都会重新分配一个pid)
在这里插入图片描述

查看proc中当前进程的目录,有以下两个文件需要认识:

cwd进程当前的工作路径
exe进程对应的可执行程序的磁盘文件

这也能说明当前进程所在的路径进程自己会维护。
在这里插入图片描述

  • 大多数进程信息同样可以使用比特科技 top和ps这些用户级工具来获取
//命令如下
ps ajx | grep 

// test.c
#include <stdio.h>    
#include <sys/types.h>    
#include <unistd.h>                             
    
int main()    
{    
    while(1)    
    {    
        printf("子进程PID:%d,父进程PPID:%d\n",getpid(),getppid());        
        sleep(1);    
    }    
    
    return 0;    
}

使用上述grep命令后我们发现屏幕上会显示有两个进程信息,这是因为grep指令也是一个进程Linux中的指令实际上就是一个一个的程序。
在这里插入图片描述
如果想去掉grep指令的进程信息可以使用如下指令:

//这种查看进程状态的方法常用
//-v表示匹配上的不显示
ps ajx | grep test | grep -v grep

//显示各项属性名称
ps ajx | head -1 && ps ajx | grep test | grep -v grep 

在这里插入图片描述

1.5 通过系统调用获取进程标识符

每一个进程在系统中,都会存在一个唯一的标识符,用来标识唯一的一个进程,也叫做pid(process id)。

  • 进程id(PID)
  • 父进程id(PPID)

注意:

  • pid_t其实是无符号整型
  • getpidgetppid系统调用接口

在这里插入图片描述

ctrl + c可以结束进程
在这里插入图片描述

也可以使用kill指令结束进程,并且kill指令可以结束后台进程(需要在另一个窗口),命令如下:

kill -9 [进程PID]

在这里插入图片描述

结论:几乎所有我们在命令行上所执行的指令,都是bash进程的子进程!(如下两图)
在这里插入图片描述
在这里插入图片描述

1.6 fork初识-通过系统调用创建进程

首先来认识fork这个系统调用的接口:
在这里插入图片描述
其返回值如下:
在这里插入图片描述
fork有两个返回值,子进程中fork返回0,父进程中fork返回子进程的pid。
从fork之后,父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)。

  • fork之后通常使用if进行分流
  • 对于C语言,函数返回值只有一个这是其一,其二C语言不能同时运行两个死循环.
//fork.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        //子进程
        while(1)
        {
            printf("这是子进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(1);
        }
    }
    else if(id > 0)
    {
        //父进程
        while(1)
        {
            printf("这是父进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(3);                                                                          
        }
    }
    return 0;
}

可以看到程序当中两个死循环同时运行,查看此时的fork进程我们发现有两个fork进程,并且这两个进程是父子进程的关系。
关于fork的返回值:

  • 父进程可以有多个进程,但子进程只能有一个父进程;
  • 而父进程可能有多个子进程,因此需要pid来标识每一个子进程;
  • 子进程最重要的是要知道自己被创建成功了,因为子进程找父进程成本很低。

在这里插入图片描述

fork函数

要回答这个问题就需要我们知道fork之后,OS做了什么;fork之后系统多了一个进程,实质就是内存中多了一个task_struct结构体以及子进程对应的代码和数据;子进程的task_struct对象内部的数据基本是从父进程继承下来的,代码和数据则是fork之后父子进程代码共享,数据各自独立(暂时了解)。
而不同的返回值可以让不同的进程执行不同的代码,让父子进程具有一定的协作。

为什么fork会返回两次?

当一个函数运行到return语句的时候,表示该函数的核心功能已经完成了。那么在return之前子进程就已经被创建了,并且运行(将task_struct放到运行队列当中);fork之后代码共享,所以父子进程各有一个return语句,因此会返回两次。

二、进程状态

在这里插入图片描述

  • 运行状态:进程只要在运行队列中就成为运行状态。
  • 终止状态:进程还在,只是不运行了,随时等待被释放。
  • 进程阻塞:进程等待某种资源(非CPU),该资源没有就绪的时候,进程需要在该资源的等待队列,这就是进程阻塞。

当进程访问某些资源(磁盘网卡),该资源如果暂时没有准备好,或者正在给其他进程提供服务,此时:

  1. 当前进程要从runqueue中移除;
  2. 将当前进程放入对应设备的描述结构体中的等待队列。

当进程在等待外部资源的时候,进程的代码不会执行,直接表现为进程卡住了。

在这里插入图片描述

  • 进程挂起:当内存不足时,操作系统会将短期内不会调度执行的进程的代码和数据从内存中替换出去,则该进程状态称为进程挂起。

进程挂起的进程的代码和数据并不是随便存放在磁盘上,而是操作系统在磁盘中维护的一块空间(swap)中。

在这里插入图片描述

在Linux内核当中,进程状态可以理解为就是一个整数:

//例如下面,当然Linux中的进程状态在task_struct
//不一定是下面这种方式
#define RUN 1   //用1表示运行  
#define STOP 2	//用2表示停止  
#define SLEEP 3	//用3表示睡眠  

2.1 Linux内核源代码

Linux中的进程状态与上述有所不同,上述概念是计算机系统的进程状态的概念,而下面要讲述的是特定系统中的进程状态。
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面的状态在内核源代码中定义:

/*
* 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 && S
R运行状态,进程要在运行队列中。
S阻塞状态,进程在等待某种资源,进程PCB在该资源的等待队列中。

一个进程运行非常快,因为运行是CPU读取内存当中的数据进行计算和控制;阻塞状态很慢因为阻塞是在等待某种外设资源,如磁盘、网卡等等,而内存从外设中读取数据的速度较之CPU无疑慢了一大截,因此一个程序从开始加载到运行完,大部分时间都是在等待外设资源和读取外设资源的数据。

因此通常查看一个需要用到外设资源的进程一般是在阻塞状态。
在这里插入图片描述

D
S 是一种阻塞状态,是浅度睡眠,可中断睡眠,操作系统和用户都可以中断其睡眠
D 是磁盘休眠状态(Disk sleep),也一种阻塞状态,有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。操作系统和用户都无权中断其睡眠

那么为什么需要这种状态呢?

在日常生活和工作当中,计算机可能需要进行大量的工作,但是计算机的内存大小是固定的,操作系统一直在运行往内存中输入数据,那么当内存满了服务器压力过大,操作系统就会终止一些用户进程,在这种情况下就可能导致信息丢失,普通的信息还好但要是非常重要的信息呢,如:银行的转账信息、用户信息等等,这就存在很大的风险。

为了解决这个问题,Linux中提供了深度睡眠状态,这种状态的进程操作系统和用户是无权终止的。

T && t
Tt都是暂停状态,只是有所区别。
T是常规暂停,可以通过发送 SIGSTOP 信号给进程来停止(T)进程,这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行;t则有所差别,当使用gdb调试代码时,程序在断点处停下来时进程就是 t 状态了。
在这里插入图片描述

使用gdb调试test程序,打上断点并运行到断点处,此时查看进程:
在这里插入图片描述

X
进程进入死亡状态,资源可以立马被回收。这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

2.2 僵尸进程-Z(zombie)

2.2.1 僵尸进程概念

僵死状态(Zombies)是一个比较特殊的状态,当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程,即处在僵尸状态的进程就叫僵尸进程。

  • 一个进程被创建一定是因为有任务让这个进程执行;
  • 僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态码;
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程就会进入Z状态。

2.2.2 模拟僵尸进程

//zombie.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        //子进程
        int count = 3;
        while(count--)
        {
            printf("这是子进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(1);
        }
        printf("子进程结束,进入僵尸状态");
        exit(1);
    }
    else if(id > 0)
    {
        //父进程
        while(1)
        {
            printf("这是父进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(3);                                                                          
        }
    }
    return 0;
}
//循环打印进程状态指令
while :; do ps ajx | head -1 && ps ajx | grep fork | grep -v grep; sleep 1; echo "-----------------------------"; done

在这里插入图片描述

2.2.2 僵尸进程危害

  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎 么样了。如果父进程一直不读取,那子进程就会一直处于Z状态;
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB就一直都要维护;
  • 如果一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费,因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

总结:僵尸进程一直存在就会造成内存泄漏

2.3 孤儿进程

2.3.1 孤儿进程概念

  • 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
  • 父进程先退出,子进程就称之为“孤儿进程”
  • 孤儿进程被1号init进程领养,当然要有init进程进行回收,1号进程就是操作系统。

孤儿进程就是被领养的进程。

2.3.1 模拟孤儿进程

    pid_t id = fork();
    if(id == 0)
    {
        //子进程
        while(1)
        {
            printf("这是子进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(1);
        }
    }    
    else if(id > 0)    
    {    
        //父进程    
        int cnt = 3;    
        while(cnt--)
        {                                                                     
            printf("这是父进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);
            sleep(1);
        }
        
        printf("父进程结束,子进程变成孤儿进程!\n");
    }
    return 0;
}

在这里插入图片描述
父进程先于子进程结束,子进程会被1号进程领养(其实就是操作系统),但是我们发现已经无法使用ctrl+c快捷键关闭该进程,这是因为子进程变成了后台程序。

注意: ctrl+c只能用来结束前台进程。

使用kill指令可以终止后台进程:

kill -9 PID

在这里插入图片描述

补充

kill 指令
功能:给目标进程发信号。
格式:kill -[选项/信号编号] 进程PID
常用选项:

  • -l:查看kill指令的信号编号。
    在这里插入图片描述

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

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

相关文章

vs2019 + qt5.12.11 打包

目录 你以为打包方式 实际要添加步骤 你以为打包方式 先吐槽一番&#xff0c;感觉vsqt打包有点巨坑&#xff0c;还是说我第一次打包其实都是这样子的 首先我们将生成的.exe弄到一个打包文件夹里面 然后嘞 我用qt自带的打包工具windeployqt exe &#xff08;因为我的再C盘下…

Mysql基础篇(11)—— MySQL8.0新特性之窗口函数

举例1 假设我现在有这样一个数据表&#xff0c;它显示了某购物网站在每个城市每个区的销售额&#xff1a; CREATE TABLE sales( id INT PRIMARY KEY AUTO_INCREMENT, city VARCHAR(15), county VARCHAR(15), sales_value DECIMAL ); INSERT INTO sales(city,county,sales_val…

【xgboost】XGBoost

XGBoost1. 原理改进及特点1.1 遵循Boosting算法的基本建模流程1.2 平衡精确性与复杂度1.3 降低模型复杂度、提升运行效率1.4 保留部份GBDT属性2. sklearn接口(回归)2.1 导库 & 数据2.2 sklearn api普通训练2.3 sklearn api交叉验证2.4 查看属性接口3. xgboost原生代码(回归…

Redis数据持久化方案

作为集中式缓存的优秀代表&#xff0c;Redis可以帮助我们在项目中完成很多特定的功能。Redis准确的说是一个非关系型数据库&#xff0c;但是由于其超高的并发处理性能&#xff0c;及其对于缓存场景所提供的一系列能力构建&#xff0c;使其成为了分布式系统中的集中缓存的绝佳选…

深入学习Vue.js(十)异步组件和函数式组件

文章目录异步组件需要解决的问题异步组件实现原理1.封装defineAsyncComponent函数2.超时与error3.延迟和Loading组件函数式组件异步组件需要解决的问题 允许用户指定加载出错时要渲染的组件允许用户指定Loading组件&#xff0c;以及展示该组件的延迟时间允许用户设置加载组件的…

8. R语言绘图系统介绍、高级绘图与低级绘图、【绘图参数】、绘图函数包

b站课程视频链接&#xff1a; https://www.bilibili.com/video/BV19x411X7C6?p1 腾讯课堂(最新&#xff0c;但是要花钱&#xff0c;我花99&#x1f622;&#x1f622;元买了&#xff0c;感觉讲的没问题&#xff0c;就是知识点结构有点乱&#xff0c;有点废话&#xff09;&…

筑基一层 —— 高质量C编程建议、详解猜数字游戏

目录 一.修炼必备 二.高质量C编程 2.1 高质量C编程的思维导图&#xff08;需要思维导图的加qq:972606225获取) 2.2 文件结构 2.3 程序的形式 2.4 命名规则 三.猜数字游戏详解 一.修炼必备 1.入门必备&#xff1a;VS2019社区版&#xff0c;下载地址&#xff1a;Visual S…

torch_geometric -- Pooling Layers

torch_geometric – Pooling Layers global_add_pool 通过在节点维度上添加节点特征来返回批量图级输出&#xff0c;因此对于单个图 它的输出由下式计算 from torch_geometric.nn import global_mean_pool, global_max_pool, global_add_pool import torch as thf [[1,2,3,4…

Wider Face+YOLOV8人脸检测

YOLO系列的算法更新实在太快了&#xff0c;前些天刚学习完YOLOV7&#xff0c;YOLOV8就出来了。今天先理解模型的训练过程&#xff0c;后续再学习V8的网络结构等细节。YOLOV8源码链接&#xff1a;https://github.com/ultralytics/ultralytics1 数据格式转换Wider Face数据格式转…

java -- 14 多态、内部类、常用API

自动类型转换&#xff1a;多态下引用数据类型的类型转换强制类型转换案例&#xff1a;定义usb接口&#xff1a;定义鼠标和键盘的usb实现类&#xff0c;并有自己特有的方法&#xff0c;重写usb接口的方法&#xff0c;里面穿插了多态创建电脑类&#xff0c;把usb接口揉和进去&…

如何改变视频的MD5值?一分钟让你学会操作

肯定很多不是从事自媒体的朋友对MD5不是很熟悉&#xff0c;但其实它类似于人的身份证&#xff0c;只不过我们的身份证是一串数字&#xff0c;而它则是视频的后台编码&#xff0c;所以这也是一些平台用MD5来判断视频是否重复的依据。那么有人会问了&#xff0c;既然MD5这么特殊&…

Java实战:使用Hutool中的MailUtil实现邮件的发送

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️荣誉&#xff1a; CSDN博客专家、数据库优质创作者&#x1f3c6;&…

EasyExcel的导入导出使用

1、说明 EasyExcel是阿里出的一款基于Java的、快速、简洁、解决大文件内存溢出的处理Excel的开源工具&#xff0c;本文主要是使用这个工具对Excel导入导出进行讲解。 官网&#xff1a; https://easyexcel.opensource.alibaba.com/github&#xff1a; https://github.com/alib…

达梦主备之备库失联后在线恢复加入集群

一、主库故障重启&#xff08;备库接管前重启&#xff09; 主库故障后立即重启&#xff0c;此时主库的守护进程变成 Startup 状态&#xff0c;重新进入守护进程的 启动流程&#xff0c;将数据一致的备库归档设置为有效状态&#xff0c;其余备库归档设置成无效状态&#xff0c;并…

一些工具软件的使用

文章目录010 Editor设置16进制编辑时每行显示的字节数使用列模式编辑VS Code基础操作定义快捷键配置导出/导入列模式将文件中的tab键转换为空格关闭插件自动更新博文链接Beyond Compare文件内容相同依然显示差异过滤文件或文件夹Excel使用组合&#xff0c;进行行、列的折叠使用…

【DX-BT24蓝牙模块-AT命令与手机透传教程】

【DX-BT24蓝牙模块-AT命令与手机透传教程】1. 前言1.1.串口基本参数1.2.AT命令模式和透传模式1.3.模块数据吞吐量2. 接线2.1 模块线序定义2.2 相关AT命令详解2.2.1 命令格式说明2.2.2 回应格式说明2.2.3 AT命令举例说明3. AT命令详解3.1 基础指令3.2 AT指令测试3.3 手机测试4. …

英华特在创业板提交注册:拟募资约5亿元,股权结构较为分散

近日&#xff0c;苏州英华特涡旋技术股份有限公司&#xff08;下称“英华特”&#xff09;在上海证券交易所递交注册。据贝多财经了解&#xff0c;英华特的上市申请于2021年6月30日获得受理&#xff0c;2022年8月25日获得创业板上市委会议通过。 本次冲刺上市&#xff0c;英华特…

智合同丨你还在为填写合同台账犯愁吗?

最近有朋友问我有没有什么智能化手段处理合同台账问题&#xff1f;对方表示合同台账管理实在是太麻烦了&#xff0c;工作量大&#xff0c;占用时间多。答案肯定是有的&#xff0c;那么首先我们来了解下合同台账。合同台账一般指合同台帐&#xff0c;包括合同登记台帐、合同检查…

Solidity 中的数学(第 1 部分:数字)

本文开启了一系列关于在 Solidity 中进行数学运算的文章。第一个要讨论的话题是&#xff1a;数字。 介绍 以太坊是一个可编程的区块链&#xff0c;其功能可以通过将称为智能合约的可执行代码片段发布到区块链本身来扩展。这将以太坊与第一代区块链区分开来&#xff0c;在第一代…

PointNet.pytorch点云三维深度学习论文与代码复现

PointNet.pytorch1. 概要1.1 文章1.2 点云和三维深度学习&#xff0c;PointNet 网络结构1.3 复现说明2. 代码2.1 代码逻辑2.2 思路详解3. 解析组会2023.1.18远程arcivdailyonedb1. 概要 1.1 文章 链接: 论文 1.2 点云和三维深度学习&#xff0c;PointNet 网络结构 链接: 三…