14-5-进程间通信-信号

news2024/9/20 8:36:25

一、信号的基本概述

1.什么是信号?

(1)对于linux来说,信号是软中断。比如在终端输入ctrl+c来中断正在运行的程序,原理是linux通过信号机制来停止一个程序。

(2)每一个信号都有一个名字和编号,名字是以"SIG"开头的,例如SIGIO,SIGCHLD等。信号是从1开始编号的,不存在0号信号。

(3)信号名都被定义为正整数。

(4)信号定义在signal.h头文件中。

(5)使用kill -l查看信号的名字和序列。信号是从1开始编号的,不存在0号信号

(6)linux下对信号的宏定义

#define SIGHUP   1 
进程由於控制终端死去或者控制终端发出起命令 

#define SIGINT   2 
键盘中断所产生的信号 
 
#define SIGQUIT   3 
键盘终止 
 
#define SIGILL   4 
非法的指令 
 
#define SIGTRAP   5 
进程遇到一个追踪(trace)或者是一个中断嵌套 
 
#define SIGABRT   6 
由abort系统调用所产生的中断信号 
 
#define SIGIOT   6 
类似於SIGABRT 
 
#define SIGBUS   7 
进程试图使用不合理的记忆体 
 
#define SIGFPE   8 
浮点异常 
 
#define SIGKILL   9 
KILL 
 
#define SIGUSR1  10 
用户自定义 
 
#define SIGSEGV  11 
段错误 
 
#define SIGUSR2  12 
用户自定义 
 
#define SIGPIPE  13 
管道操作时没有读只写 
 
#define SIGALRM  14 
由alarm系统调用产生的timer时钟信号 
 
#define SIGTERM  15 
收到终端信号的进程 
 
#define SIGSTKFLT 16 
堆叠错误 
 
#define SIGCHLD  17 
子进程向父进程发出的子进程已经stop或者终止的信号 
 
#define SIGCONT  18 
继续运行的信号 
 
#define SIGSTOP  19 
stop 
 
#define SIGTSTP  20 
键盘所产生的stop信号 
 
#define SIGTTIN  21 
当运行在後状态时却需要读取stdin的资料 
 
#define SIGTTOU  22 
当运行在後状态时却需要写向stdout 
 
#define SIGURG  23 
socket的紧急情况 
 
#define SIGXCPU  24 
进程超额使用CPU分配的时间 
 
#define SIGXFSZ  25 
进程使用了超出系统规定文件长度的文件 
 
#define SIGVTALRM 26 
内部的alarm时钟过期 
 
#define SIGPROF  27 
在一个程式段中描绘时钟集过期 
 
#define SIGWINCH 28 
终端视窗的改变 
 
#define SIGIO  29 
非同步IO 
 
#define SIGPOLL  SIGIO 
pollable事件发生 
————————————————
版权声明:本文为CSDN博主「hnzmdzcm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenming_zhang/article/details/7824502

名称--------默认动作---------说明---------------------
SIGHUP  	终止进程    	    终端线路挂断
SIGINT  	终止进程    	    中断进程
SIGQUIT 	建立CORE文件	    终止进程,并且生成core文件
SIGILL  	建立CORE文件    非法指令
SIGTRAP 	建立CORE文件    跟踪自陷
SIGBUS  	建立CORE文件    总线错误
SIGSEGV 	建立CORE文件    段非法错误
SIGFPE  	建立CORE文件    浮点异常
SIGIOT  	建立CORE文件    执行I/O自陷
SIGKILL 	终止进程    	   杀死进程
SIGPIPE 	终止进程    	    向一个没有读进程的管道写数据
SIGALARM    终止进程    	    计时器到时
SIGTERM 	终止进程    	    软件终止信号
SIGSTOP 	停止进程    	    非终端来的停止信号
SIGTSTP 	停止进程    	    终端来的停止信号
SIGCONT 	忽略信号    	    继续执行一个停止的进程
SIGURG  	忽略信号    	    I/O紧急信号
SIGIO   	忽略信号    	    描述符上可以进行I/O
SIGCHLD 	忽略信号    	    当子进程停止或退出时通知父进程
SIGTTOU 	停止进程    	    后台进程写终端
SIGTTIN 	停止进程        	后台进程读终端
SIGXGPU 	终止进程    	    CPU时限超时
SIGXFSZ 	终止进程    	    文件长度过长
SIGWINCH    忽略信号    	    窗口大小发生变化
SIGPROF 	终止进程    	    统计分布图用计时器到时
SIGUSR1 	终止进程    	    用户定义信号1
SIGUSR2 	终止进程    	    用户定义信号2
SIGVTALRM   终止进程    	    虚拟计时器到时
————————————————
版权声明:本文为CSDN博主「hnzmdzcm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenming_zhang/article/details/7824502

2.信号处理的方式

 (1)信号的处理方法有3种:忽略,捕捉,默认动作。 

(2)关于忽略信号:

        (忽略信号)有两种信号不能被忽略:SIGKILL,SIGSTOP。因为他们向内核和超级用户提供了进程停止和终止的可靠方法。如果这两个信号可以被忽略,那么可能引起以下问题:假如有恶意进程(病毒)在运行,普通用户或超级用户会发送SIGKILL来杀掉这个进程,如果此时SIGKILL信号被忽略,那么恶意程序将变成没人能管理的程序,因此带来无法估计的后果。内核设计者在设计之初就这么设计的,相当于开了上帝视角给自己留一手。

(3)关于捕捉信号:      

        (捕捉信号)是一种信号处理函数,和单片机的中断处理函数很像。开发人员写一个信号处理函数,当指定信号出现时,通知内核,然后内核调用开发者自定义的服务函数。

(4)关于默认动作

        对于每一个信号来说,系统都有一个默认的处理动作,当该信号发生时系统会自动执行。系统处理大多数信号的动作是杀死该进程。其他的处理动作可以通过指令man 7 signal查看。

3.如何使用信号?

(杀死信号)kill -9 进程id号

  (杀死信号的第二种方法)kill -SIGKILL 进程id号

(查看进程id号)ps

4.信号除了被杀死,还有哪些意义?

答:信号是实现异步通信的手段(利用捕捉信号实现异步通信)。

5.怎样自定义信号处理函数?

(相关api)

#include <signal.h>

typedef void (*sighandler_t)(int);//这是声明的一种指针类型

sighandler_t signal(int signum, sighandler_t handler);

6.实验

(1)实验一:自定义信号处理函数

#include"stdio.h"
#include "signal.h"

void handler(int signum)
{
        printf("get signum =%d\n",signum);
        switch(signum)
        {
                case 1:
                        printf("SIGINT\n");

                        break;
                case 9:
                        printf("SIGKILL\n");
                        break;
                case 10:
                        printf("SIGUSR1\n");
                        break;
        }
}

int main()
{
        signal(SIGINT,handler);
        signal(SIGKILL,handler);
        signal(SIGUSR1,handler);

        while(1);
        return 0;
}

 (2)实验二:写一个demo,运行一个可执行文件来杀死指定进程

注意:要使用到int main(int argc,char **argv)来传递参数;

int main(int argc,char* argv[]) 也可以写成 int main(int argc,char** argv)。

argc表示程序运行时发送给main函数的命令行参数的个数(包括可执行程序以及传参)。
argv[]是字符指针数组,它的每个元素都是字符指针,指向命令行中每个参数的第一个字符。
argv[0]指向可执行程序。
argv[1]指向可执行程序后的第一个字符串。
argv[2]指向可执行程序后的第二个字符串 。
argv[3]指向可执行程序后的第三个字符串 。
argv[argc]为NULL。

编写了以下c文件(功能:执行可执行文件,后面跟2个参数,就能杀死指定进程(这两个参数分别是信号值9和进程号))

#include "stdio.h"
#include "signal.h"
#include "sys/types.h"

int main(int argc,char **argv)
{
        int signum;
        int pid;

        signum = atoi(argv[1]);
        pid = atoi(argv[2]);

        printf("signum = %d,pid = %d\n",signum,pid);

        kill(pid,signum);
        printf("send signal ok\n");

        return 0;
}
  

如图:先执行第一个demo:./a.out(执行这个demo,过一会用demo2来杀死他);

接着查看该进程号为37754;

然后执行"./killProcess 9 37754"杀死37754进程;

可以看到终端上显示Killed;

atoi();是ascii转整形的函数

kill:发送信号,指定将信号发送给某个进程,常用来杀掉进程,可以通过pstop命令来查看进程(这是入门级别的发送信号方式);

kill(pid,signum);也可以写成

char cmd[128]={0};

sprintf(cmd,"kill -%d %d",signum,pid);

system(cmd);

(3)忽略一个指定信号

使用SIG__IGN

#include"stdio.h"
#include "signal.h"



int main()
{
        signal(SIGINT,SIG_IGN);
        signal(SIGKILL,SIG_IGN);
        signal(SIGUSR1,SIG_IGN);

        while(1);
        return 0;
}

运行结果 如图:

键盘输入ctrl+c无效,说明忽略“ctrl+c”信号成功(ctrl+c信号对应的是signum =2 );

键盘输入“kill -9 4271”后,程序退出运行;说明 无法忽略SIGKILL信号

二、信号如何携带消息(入门级+高级)

1.概述

入门级:(只有信号,没有消息)

        kill(发送信号);

        signal(接收信号);

高级:(既有信号,又有消息)

        需要探讨以下几个问题:     

                接收消息:

                        问题1:来信号时怎么处理(怎么绑定)?----sigaction

                        问题2:来信号时如何读出消息?

                        问题3:信号如何携带消息?

                发送消息:

                        问题4:用什么发送?---sigqueue

                        问题5:怎么放入消息?

2.API的介绍

自己描述的不清晰,可直接参考这篇博客:linux C编程10-信号_siginfo_t_邻居家的小南瓜的博客-CSDN博客信号是事件发生时对进程的通知机制,也可以把它称为软件中断。信号与硬件中断的相似之处在于能够打断程序当前执行的正常流程, 其实是在软件层次上对中断机制的一种模拟。 大多数情况下,是无法预测信号达到的准确时间,所以,信号提供了一种处理异步事件的方法。Linux 内核定义了 31 个不同的实时信号,信号编号范围为 34~64,使用 SIGRTMIN 表示编号最小的实时信号,使用 SIGRTMAX 表示编号最大的实时信号,其它信号编号可使用这两个宏加上一个整数或减去一个整数。实时信号较之于...https://blog.csdn.net/qq_37932504/article/details/118366865

(1)sigaction(来信号时怎么处理)

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

三个参数的作用:信号的值,信号处理函数,备份原有信号(当该指针为空时无数据,指针非空时有数据)

参数 signum: 需要设置的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号。

参数 act: act 参数是一个 struct sigaction 类型指针,指向一个 struct sigaction 数据结构,
该数据结构描述了信号的处理方式;如果参数 act 不为 NULL,则表示需要为信号设置新的处理方式;
如果参数 act 为 NULL,则表示无需改变信号当前的处理方式。

oldact: oldact 参数也是一个 struct sigaction 类型指针,指向一个 struct sigaction 数据结构。
如果参数oldact 不为 NULL, 则会将信号之前的处理方式等信息通过参数 oldact 返回出来;
如果无意获取此类信息,那么可将该参数设置为 NULL。
返回值: 成功返回 0;失败将返回-1,并设置 errno。
struct sigaction
 {
  void   (*sa_handler)(int);//函数指针
  void   (*sa_sigaction)(int signum, siginfo_t *info, void *context);//函数指针(用于绑定某些参数)
  sigset_t   sa_mask;//结构体
  int        sa_flags;
  void     (*sa_restorer)(void);
};

理解:
sigaction可以为某些信号设置回调,这些设置都在struct sigaction中进行
(1)void (*sa_handler)(int)信号处理函数;
    其取值如下:
        SIG_IGN  忽略该信号;
        SIG_DEL  执行系统默认动作;
注意:如果配置这个回调,则效果和signal一致。无法接收消息!!!!!!!!!

(2)void (*sa_sigaction)(int signum,siginfo_t *info,void *context)也是信号处理函数,
当sa_flag为SA_SIGFINFO时将使用该函数。
注意:配置这个回调时,才能接收消息!!!!!!!!!!!!!!!
3个参数:
    参数1 :signum是信号的值。
    参数2 :一个结构体,后面会描述;
    参数3 : void *context;//空或非空用来判断是否有内容

上述两个信号函数是互斥的,一次只能使用两个字段中的一个!!!!!!!!!!!!!!!
因此在一些实现中,使用union来存放这两个函数。




(3)sigset_t sa_mask 是一个sigset,可以在信号处理函数执行的时候起到阻塞的作用。
(sa_mask  信号阻塞集,在信号处理函数执行过程中,临时屏蔽指定信号;);
sigset_t sa_mask可以不配置,不配置时默认为阻塞。

(4)int sa_flags 这是一个选项字段。
比如说:
SA_RESART 使被信号打断的系统调用自动重新发起(己废弃);
SA_NOCLDSTOP 使父进程在它的子进程暂停或继续运行时不会收到SIGCHLD信号;
SA_NOCLDWAIT 使父进程在它的子进程退出时不会收到SIGCHLD信号,
这时子进程如果退出也不会成为僵尸进程;
SA_NODEFER   使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号;
SA_RESETHAND 信号处理之后重新设置为默认处理方式;
SA_SIGINFO   使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数!!!!!!

(5)sa_restorer:该成员已过时,不要再使用了。
siginfo_t结构体的原型如下:
siginfo_t {
    int si_signo; /* Signal number */
    int si_errno; /* An errno value */
    int si_code; /* Signal code */
    int si_trapno; /* Trap number that caused hardware-generated signal(unused on most
    architectures) */
    pid_t si_pid; /* Sending process ID */
    uid_t si_uid; /* Real user ID of sending process */
     int si_status; /* Exit value or signal */
    clock_t si_utime; /* User time consumed */
    clock_t si_stime; /* System time consumed */
    sigval_t si_value; /* Signal value */
    int si_int; /* POSIX.1b signal */是接收端想要获取的数据
    void *si_ptr; /* POSIX.1b signal */
    int si_overrun; /* Timer overrun count; POSIX.1b timers */
    int si_timerid; /* Timer ID; POSIX.1b timers */
    void *si_addr; /* Memory location which caused fault */
    long si_band; /* Band event (was int in glibc 2.3.2 and earlier) */
    int si_fd; /* File descriptor */
    short si_addr_lsb; /* Least significant bit of address(since Linux 2.6.32) */
    void *si_call_addr; /* Address of system call instruction(since Linux 3.5) */
    int si_syscall; /* Number of attempted system call(since Linux 3.5) */
    unsigned int si_arch; /* Architecture of attempted system call(since Linux 3.5) */
}
 

(2)如何发送消息?---sigqueue

(sigqueue函数原型)
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);
参数 pid(解决了发给谁的问题): 指定接收信号的进程对应的 pid,将信号发送给该进程。
参数 sig(解决了发送什么信号的问题): 指定需要发送的信号。与 kill()函数一样,也可将参数 sig 设置为 0,用于检查参数 pid 所指定的进程是否存在。
参数 value(发送的消息,消息可以是整型或char型): 参数 value 指定了信号的伴随数据, union sigval 数据类型。

3.编程实验

功能:

写一个接收处理的c文件(sigaction_demo.c)和一个发送信号的c文件(sigqueue_demo.c);(sigaction_demo.c可以打印信号值和携带的消息;sigqueue_demo.c可以发送信号)

编译(分别生成可执行文件sigaction和sigqueue);

先执行接收程序sigaction,查看该进程号为xxxxxx(比如:39962);

再执行发送程序./sigqueue 10 xxxxx(比如:39962);

观察打印信息;

思路:

首先 考虑接收端的实现:

接收端利用sigaction();

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

第一个参数配置为:SIGUSR1(用户自定义的)

第二餐参数是1个结构体:

struct sigaction

 {

        void     (*sa_handler)(int);//函数指针

         void     (*sa_sigaction)(int, siginfo_t *info, void *context);//函数指针(用于绑定某些参数)

        sigset_t   sa_mask;//结构体

       int        sa_flags;

       void     (*sa_restorer)(void);

};

1)不使用第一个回调;(因为使用它无法接收消息)

2)使用第二个回调;(注意sa_flags配置为SA_SIGINFO,该回调才被用来接收消息)

3)sa_mask可以不配置,不配置时默认为阻塞();

4)sa_flags要配置为SA_SIGINFO(因为使用第二个回调接收消息,则sa_flags要配置为SA_SIGINFO)

5)sa_restorer:该成员已过时,不要再使用了。

第三个参数,无意获得此类信息,所以配置为NULL

所以接收端的代码如下:

#include "stdio.h"
#include "signal.h"


void handler(int signum,siginfo_t *info,void *context)
{
        printf("get signum %d\n",signum);

        if(context != NULL)
        {
                printf("get data = %d\n",info->si_int);
                printf("get data = %d\n",info->si_value.sival_int);

        }
}

int main()
{
        struct sigaction act;
        act.sa_sigaction = handler;
        act.sa_flags = SA_SIGINFO ;

        sigaction(SIGUSR1,&act,NULL);
        while(1);
}

接下来考虑发送端的实现

发送端的实现依赖sigqueue

设计思路如下:

指定信号值为10;

pid依赖linux指令“ps -aux | grep xxxx”来查看(比如发送端的可执行文件叫“a.out”,则ps -aux | grep a.out来查看pid)

信号携带的值value,可以随便定义(因为是实验)。项目中要看具体的应用了。

代码如下:

#include "stdio.h"
#include "signal.h"

int main(int argc,char **argv)
{
        int signum;
        int pid;

        signum = atoi(argv[1]);
        pid = atoi(argv[2]);

        union sigval value;
        value.sival_int = 100;
        sigqueue(pid,signum,value);

        printf("done\n");

        return 0;
}
~        

运行结果如图:

信号值为10;携带的消息是100;(注意可以在sigaction_demo.c的函数中添加printf(“sender_id = %d\n”,info->si_pid);来打印发送者的pid

 

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

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

相关文章

Django项目页面样式如何“传给”客户端浏览器

前言 django项目在视图函数中借助render函数可以返回HTML页面&#xff0c;但是HTML页面中如果引入了外部CSS文件或者JavaScript文件在浏览器页面无法加载&#xff0c;因此就必须有一种方式能够将HTML文档中引入的外部文件能够在客户端浏览器上加载&#xff0c;这种方式就是配置…

QML状态与过渡(States and Transitions)

目录 一 状态&#xff08;States&#xff09; 一 过渡&#xff08;Transitions&#xff09; 通常我们将用户界面描述为一种状态。一个状态定义了一组属性的改变&#xff0c;并且会在一定的条件下被触发。另外在这些状态转化的过程中可以有一个过渡&#xff0c;定义了这些属性…

第二十章 中介者模式

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

SpringSecurity框架学习与使用

SpringSecurity框架学习与使用 SpringSecurity学习SpringSecurity入门SpringSecurity深入认证授权自定义授权失败页面权限注解SecuredPreAuthorizePostAuthorizePostFilterPreFilter 参考 SpringSecurity学习 SpringSecurity入门 引入相关的依赖&#xff0c;SpringBoot的版本…

IPsec中IKE与ISAKMP过程分析(快速模式-消息3)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息3&#xff09;_搞搞搞高傲的博客…

Spring - IoC

Spring - IoC Spring- IoC1)Spring简介1.1)什么是框架1.2)框架的作用1.3)Spring是什么1.4)Spring的体系结构1.5)Spring的发展历史1.6)Spring优势 2)IoC简介2.1)优质程序代码的制作原则2.2)耦合与内聚2.3)工厂模式发展史2.4)Spring发展历程2.5)IoC 3)入门案例3.1)案例环境说明3.…

synchronized用法加锁原理

目录 使用场景不同场景加锁对象结论验证实验实验1&#xff1a; synchronized 修饰方法&#xff0c;加锁对象是类实例&#xff0c;不同实例之间的锁互不影响实验2&#xff1a; synchronized 加在静态方法上&#xff0c;加锁对象是方法所在类&#xff0c;不同类实例之间相互影响实…

docker镜像导入导出

项目背景 1. docker pull 的时候比较慢的情况下&#xff0c; 之前已经下载过的话&#xff0c;可以直接导入使用 2. 有些服务器不允许上外网的情况下&#xff0c;可以先在自己电脑上下载好&#xff0c;再上传到服务器上进行安装 导出镜像 查看镜像 docker images 导出镜像 …

【文件系统】

目录 1 inode 2 软链接 3 硬链接 1 inode 当我们创建一个文件时&#xff0c;用带上 -i 选项可以查看文件的inode: 其中第一个选项就是文件的inode,除此之外另外几列表示的是&#xff1a; 模式 硬链接数 文件所有者 所属组 大小 最后修改时间文件名 ls -l读取存储在磁盘上的文…

windows编译安卓源码记录

环境 Windows10 vmware17 ubuntu22 ubuntu环境设置 装完ubuntu系统后拖拽复制文件进去验证vmtools安装情况&#xff0c;如果vmtools异常很麻烦&#xff0c;试了n多方法&#xff0c;最后还是重新安装系统解决&#xff0c; 如果ok的话&#xff0c;再继续下步骤&#xff0c;否…

【C++入门第四期】类和对象 ( 上 )

前言类的使用类的定义类的两种定义方式&#xff1a;成员变量名的定义建议 类的访问限定符类的作用域类的实列化如何计算类的大小结构体内存对齐规则 this指针this指针的特性 前言 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过…

Linux的目录结构

在Linux世界里&#xff0c;一切皆文件硬件如显卡、cpu等都会映射成一个文件具体的目录结构/bin 是Binary的缩写&#xff0c;这个目录存放着最经常使用的命令 /sbin(/usr/sbin、/usr/local/sbin) s就是Super User的意思&#xff0c;这里存放的是系统管理员使用的系统管理程序 /h…

Elasticsearch扫盲篇

1. 什么是搜索&#xff1f; 在日常的工作和学习中&#xff0c;当我们说想找查询任何的信息的时候&#xff0c;可能第一时间会想到上百度或者谷歌去搜索一下。比如说找一部自己喜欢的电影&#xff0c;或者说找一本喜欢的书&#xff0c;或者找一条感兴趣的新闻。但是百度和谷歌不…

QML基础模型(Basic Model)

最基本的分离数据与显示的方法是使用Repeater元素。它被用于实例化一组元素项&#xff0c;并且很容易与一个用于填充用户界面的定位器相结合。 最基本的实现举例&#xff0c;repeater元素用于实现子元素的标号。每个子元素都拥有一个可以访问的属性index&#xff0c;用于区分不…

第11章 项目人力资源管理

文章目录 项目人力资源管理 过程11.2.1 编制项目人力资源计划的工具与技术 375&#xff08;1&#xff09;层次结构图&#xff08;工作、组织、资源 分解结构&#xff09;&#xff08;2&#xff09;矩阵图&#xff08;责任分配矩阵&#xff0c;RAM&#xff09;&#xff08;3&…

KinectFusion中的ICP算法

投影数据关联-求匹配点 利用算法projective data association对前一帧和当前帧的&#xff08;Vertex、Normal&#xff09;进行匹配&#xff0c;算法如下&#xff1a; 在当前帧 i 的深度图像上的每一个像素 U并行计算&#xff1b;对于深度值大于0的像素&#xff0c;求该像素点…

从破解虫脑到攻克人脑:一条“永生之路”的新赛道?

从破解虫脑到攻克人脑&#xff1a;一条“永生之路”的新赛道&#xff1f; 首张果蝇大脑连接组&#xff1a;耗费十余年&#xff0c;重建三千神经元&#xff0c;超50万突触&#xff01; 论文地址 果蝇幼虫大脑的连接组。 所有脑神经元的形态学都经过了突触分辨率的电子显微镜成像…

聊天机器人开发实战--(微信小程序+SpringCloud+Pytorch+Flask)【后端部分】

文章目录 前言架构SpringCloud服务构建后台搭建Python服务调用 Python算法服务app 总结 前言 趁着五一有时间&#xff0c;先把大三下个学期的期末作业做了&#xff0c;把微信小程序和Java开发的一起做了。顺便把机器学习的也一起做了。所以的话&#xff0c;我们完整项目的技术…

如何用ChatGPT做书籍、报告、文件的读取与互动式问答?故事人物活起来

该场景对应的关键词库&#xff08;15个&#xff09;&#xff1a; 书籍、报告、文件、详细信息、查询、主题、作者、出版日期、出版社、问题、方面、原则、方法、概括、主要观点、解释。 注意&#xff1a; ChatGPT的知识库截止于2021年9月&#xff0c;对于更新的数据或最新出版…