【Linux】进程信号 --- 信号产生
👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍
目录
- 一、通过终端按键产生信号
- 1.1 Ctrl + /
- 1.2 Ctrl + z
- 二、通过kill命令产生信号
- 三、通过系统调用接口产生信号
- 3.1 kill
- 3.2 raise
- 3.3 abort
- 四、硬件异常产生信号
- 4.1 除 0 错误导致异常
- 4.2 状态寄存器
- 4.3 野指针异常
- 五、软件条件产生信号
- 5.1 alarm 函数
- 六、核心转储 core dump
- 6.1 知识回顾
- 6.2 打开与关闭核心转储
- 6.3 核心转储的作用
一、通过终端按键产生信号
1.1 Ctrl + /
在上篇博客中(点击跳转),我们已经验证了Ctrl + c
是向前台进程发送2
号信号SIGINT
来中断程序。
这篇再介绍一个组合键:Ctrl + \
。它其实是向前台进程发送3
号信号SIGQUIT
来终止程序,同时会产生一个core
文件。我们可以使用捕捉信号函数signal
来验证。
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;void myhandler(int signum)
{// 修改的行为:打印信号编号后退出cout << "信号编号为:" << signum << endl;exit(1);
}int main()
{// 捕捉3号信号signal(SIGQUIT, myhandler);while (true){cout << "我是一个进程,我在做死循环操作" << endl;sleep(1);}return 0;
}
【程序结果】
其原理再简单重复一遍:当按下ctrl + \
,操作系统识别到键盘上有数据,触发了硬件中断,CPU
收到中断请求后,会暂停当前执行的程序,保存当前状态,并根据中断号来调用对应硬件的方法。由于操作系统识别到是特殊控制字符,就将其转化为3
号信号发送给前台进程
1.2 Ctrl + z
Ctrl + z
会向前台进程发送19
号信号SIGSTOP
。当进程收到此信号时,它会立即停止运行。
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;int main()
{while (true){cout << "我是一个进程,我在做死循环操作" << endl;sleep(1);}return 0;
}
【程序结果】
需要注意的是:19
号信号SIGSTOP
不能使用signal
函数捕捉。类似地,9
号信号SIGKILL
用于立即终止一个进程,并且也不能被signal
函数捕捉。
二、通过kill命令产生信号
kill -n <pid>
# n是信号编号
以以下代码为例:
#include <iostream>
#include <unistd.h>
using namespace std;int main()
{while (true){cout << "进程:" << getpid() << ", 我在做死循环啦~" << endl;sleep(1);}return 0;
}
【程序结果】
三、通过系统调用接口产生信号
3.1 kill
系统调用kill
函数是用于向进程发送某种信号,其函数原型如下:
#include <sys/types.h>
#include <signal.h>int kill(pid_t pid, int sig);
参数解释:
pid
:要发送信号的进程pid
sig
:要发送的信号编号,可以是标准信号如SIGINT
、SIGKILL
,也可以是用户自定义的信号。- 返回值:成功时,返回
0
;失败时,返回-1
,并设置errno
来指示错误的原因。
我们可以使用这个kill
系统调用接口来模拟实现一个kill
命令。首先kill
命令必须是如下形式:
kill -信号编号 进程pid
那么这里就可以巧用main
函数的参数。main
函数的第一个参数argc
:表示字符指针数组当中的有效元素个数。argv
:是一个字符指针数组(向量表),数组以NULL指针结尾,注意argv
的第一个值原因是程序名。
因此,代码如下:
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <signal.h>
#include <sys/types.h>using namespace std;void Usage(string proc)
{cout << "格式:\n\t" << proc << " signum pid\n\n";
}// argv:程序名argv[0]、信号编号argv[1]、进程pid argv[2]
int main(int argc, char *argv[])
{// 如果是三个参数,可以杀掉用户指定进程if (argc == 3){int signum = stoi(argv[1]);pid_t pid = stoi(argv[2]);int n = kill(pid, signum);if (n != 0){perror("kill");exit(2);}}// 如果不是输入三个参数,就提醒用户输入格式else{Usage(argv[0]);exit(1);}return 0;
}
接下来我再写一个死循环代码程序如下:
#include <unistd.h>
#include <iostream>
using namespace std;int main()
{while (true){cout << "my pid is " << getpid() << endl;sleep(1);}return 0;
}
【程序结果】
3.2 raise
raise
函数用于向当前进程发送一个信号。它的基本形式如下:
#include <signal.h>int raise(int sig);
sig
:要发送的信号编号,可以是标准信号(如SIGINT
、SIGTERM
等),也可以是用户自定义的信号。- 返回值:成功时,返回
0
;失败时,返回非0
值。
这个函数可以这么理解:相当于一颗地雷,当程序“踩到”它,就会产生信号并执行。
例如:程序是死循环打印,当打印完3条消息后,就立马杀掉进程。
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>using namespace std;int main()
{int cnt = 3;while (true){cout << "My pid is " << getpid() << endl;sleep(1);cnt--;if (cnt == 0){// 9号信号raise(SIGKILL);}}return 0;
}
【程序结果】
这个函数通常搭配signal
函数使用。因为有些信号终止程序不会像9号信号一样给killed
提示,比方说2
号信号SIGINT
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>using namespace std;int main()
{int cnt = 3;while (true){cout << "My pid is " << getpid() << endl;sleep(1);cnt--;if (cnt == 0){// 2号信号raise(SIGINT);}}return 0;
}
【程序结果】
当加了signal
函数后,就直观很多了。代码如下:
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>using namespace std;void handler(int signum)
{cout << "我得到了2号信号SIGINT" << endl;exit(1);
}int main()
{signal(2, handler);int cnt = 3;while (true){cout << "My pid is " << getpid() << endl;sleep(1);cnt--;if (cnt == 0){// 2号信号raise(SIGINT);}}return 0;
}
【程序结果】
这个函数其实封装了系统调用接口kill
,例如以上代码等价于kill(getpid(), 2);
3.3 abort
abort
函数用于向自己发送一个6
号信号SIGABRT
,异常终止当前进程的执行。
函数原型如下:
#include <stdlib.h>void abort(void);
【代码样例】
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>using namespace std;void handler(int signum)
{cout << "我得到了6号信号SIGABRT" << endl;exit(1);
}int main()
{signal(6, handler);int cnt = 3;while (true){cout << "My pid is " << getpid() << endl;sleep(1);cnt--;if (cnt == 0){abort();}}return 0;
}
【程序结果】
值得一提的是,abort
函数即使在修改执行动作后(没有exit(int)
),最后仍然会发送6
号信号来退出进程。
因此,abort
函数也是被封装的,相当于kill(getpid(), 6);
总的来说,系统调用中举例的这三个函数关系是:kill
包含raise
,raise
包含 abort
,作用范围是在逐渐缩小的
四、硬件异常产生信号
4.1 除 0 错误导致异常
程序异常本质是进程收到了某种信号。
比方说,我们可以使用signal
函数来捕捉除0
异常的进程收到了几号信号。
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>using namespace std;void handler(int signum)
{cout << "我收到了" << signum << "号信号" << endl;
}int main()
{for (int i = 1; i <= 31; i++){signal(i, handler);}printf("1 / 0 = %d\n", 1 / 0);return 0;
}
【程序结果】
从上我们发现:
- 操作系统发送
8
号信号SIGFPE
- 只发生了一次 除
0
异常,进程非但没退出,还在死循环打印。
首先大部分进程对信号的处理行为都是终止程序,这里没有终止程序是因为我们修改了系统默认的行为,在handler
函数最后一行补上exit
函数即可正常终止。
但非常奇怪的是,我们代码中只有一次除0
异常啊,正常来说只需要打印一次就行了,即使进程没有退出,将进程阻塞不就好了。为什么会一直死循环打印呢?想要明白背后的原理,需要先认识一下状态寄存器。
4.2 状态寄存器
代码中除
0
和野指针行为,操作系统是怎么知道的呢?
在CPU
中,存在很多寄存器,其中大部分主要用来存储数据信息,用于运算。除此之外,还存在一种特殊的 寄存器:状态寄存器。这个寄存器是一个位图结构。专门用来检测当前进程是否出现错误行为。如果有,就会把位图结构中对应的比特位置设置成1
,意味着出现了异常。
当检测到状态寄存器中某个异常标志位被设置为1
时,硬件(寄存器)会向CPU
发送一个硬件中断,CPU
收到来自硬件的中断信号后,又因为操作系统是这些硬件的“管理者”,它会暂停当前正在执行的进程。然后检查当前进程的上下文异常标志位的具体含义,以确定发生了什么样的异常。根据异常类型调用相应的异常处理程序。这些程序通常是预先定义好的。
所以现在就可以解释为什么进程收到来自操作系统的异常信号后,虽然我们修改了默认处理动作(不退出),但是会死循环打印的情况。这是因为操作系统一直检测当前进程的状态寄存器仍然处于异常状态,再加上不退出进程,此时进程一直在被调度运行,所以操作系统才会不断发送8
号信号,才会死循环式的打印。
因此,异常信号被捕捉不是为了解决什么问题,而是让用户清除的知道程序是因为什么而挂掉的。
4.3 野指针异常
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <string>
#include <signal.h>
using namespace std;int main()
{int *p = nullptr;*p = 10;return 0;
}
【程序结果】
Segmentation fault
是一个段错误,这是每个C/C++
程序猿都会遇到的问题,因为太容易触发了,出现段错误问题时,操作系统会发送11
号SIGSEGV
信号终止进程,这里不再证明演示。
那么 野指针问题是如何引发的呢?本质上就是:虚拟地址转化为物理地址失败。比方说:虚拟地址映射到不属于它的物理空间(越界访问)、对该物理空间没有写的权限等。具体解释如下:
-
当代的
MMU
已经被集成在CPU
内部,除此之外CPU
还有一个寄存器,称为BadVAddr
(Bad Virtual Address
,坏虚拟地址)。这个寄存器的作用是在虚拟地址转换失败时,将引起异常的虚拟地址存储起来。 -
所以,硬件(寄存器)会向
CPU
发送一个硬件中断,CPU
收到来自硬件的中断信号后,又因为操作系统是这些硬件的“管理者”,它会暂停当前正在执行的进程。然后检查当前进程的上下文异常标志位的具体含义,以确定发生了什么样的异常。根据异常类型调用相应的异常处理程序。这些程序通常是预先定义好的。
五、软件条件产生信号
异常不仅由硬件产生,还可以由软件产生!
比如我们之前的管道,如果一开始读写端都打开,但是关闭了读端,那么写端进程就会收到一个13
号信号SIGPIPE
。这就是一种软件异常。【Linux】进程间通信之匿名管道
5.1 alarm 函数
alarm
函数是一个系统调用接口,用来设置一个定时器。其功能是:在指定的秒数后发送14
号信号SIGALRM
给调用进程。该信号的默认处理动作是终止当前进程。
原型如下:
#include <unistd.h>unsigned int alarm(unsigned int seconds);
seconds
:指定的秒数,即多少秒后发送SIGALRM
信号。如果参数为0
,则任何已设置的定时器都会被取消,但不会产生信号。- 返回值:返回调用之前的剩余定时器时间。如果之前没有设置定时器,则返回
0
。 aralm
函数的原理:我们知道每个进程都可以使用alarm
设置闹钟,所以操作系统中一定有大量的闹钟。所以操作系统要管理闹钟,所以闹钟就会用struct
结构体描述,一定有进程pid
(表示哪个进程设置的闹钟)等字段,然后用链表等数据结构管理起来。这样所谓的闹钟管理就变成了对链表等的增删查改。操作系统底层中alarm
的底层所用的时间用的是时间戳,只要系统的当前时间大于等于里面设置的时间,就会发送信号。我们遍历链表的时候是比较浪费时间的。所以用一个小堆是最简单的。
【代码样例】
#include <iostream>
#include <unistd.h>
#include <stdlib.h>using namespace std;int main()
{// 设定一个5s的定时器alarm(5);int n = 1;while (true){cout << "我是一个进程,已经运行了 " << n++ << " 秒 PID: " << getpid() << endl;sleep(1);}return 0;
}
【程序结果】
那我们就可以在执行主要任务的同时,去定时完成其他任务了。例如:
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>using namespace std;void work()
{cout << "我在完成其他任务" << endl;
}void handler(int signum)
{// 异常捕捉时,再设置一个定时器完成其他任务alarm(5);work();
}int main()
{// 设定一个5s的定时器alarm(5);// 信号捕捉signal(14, handler);int n = 1;while (true){// 主要任务cout << "我是一个进程,已经运行了 " << n++ << " 秒 PID: " << getpid() << endl;sleep(1);}return 0;
}
【程序结果】
六、核心转储 core dump
6.1 知识回顾
我们可以使用以下命令来看信号的详细信息手册
man 7 signal
我们可以注意到,常见的信号中大部分是终止Term
(terminate
)信号的。还有一些是暂停(Stop
),继续(Cont
),忽略(Ign
)。
那么这个核心Core
是什么东西呢?
在我们当时学习进程控制的时候,还有一个这个字段core dump
标志我们还没提到过(【Linux】进程控制 )
当一个进程异常退出时(参看上面Action
为Core
信号),该core dump
标志会被设置成1
,并且会生成一个core.pid
二进制文件,然后不再设置退出码(为0
,因为这种情况下程序没有正常的执行路径结束)
我们可以写代码来验证一下:
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>using namespace std;int main()
{pid_t pid = fork();if (pid == 0) // 子进程{int cnt = 500;while (cnt--){cout << "I am child process, pid:" << getpid() << ", cnt:" << cnt << endl;sleep(1);}// 打印5句话后子进程退出exit(1);}else // 父进程{int status = 0;pid_t rid = waitpid(pid, &status, 0);if (rid == pid){cout << "child quit info, rid:" << rid << ", exit code:" << ((status >> 8) & 0xff)<< ", exit signal:" << (status & 0x7f) << ", core dump:" << ((status >> 7) & 1)<< endl;}}return 0;
}
【程序结果】
为什么没有生成核心转储文件啊?难道是我们的环境有问题吗?
确实,当前环境确实有问题,因为它是云服务器,而云服务器中默认是关闭核心转储功能的。
6.2 打开与关闭核心转储
通过以下指令可以查看当前系统中的资源限制情况
ulimit -a
可以看到,当前系统中的核心转储文件大小为0
,即不生成核心转储文件。
通过以下指令手动设置核心转储文件大小(打开核心转储文件)
ulimit -c <大小自己定>
# 关闭大小设置为0即可
# 重启xhell自动关闭
我们可以再来测试一下,是否dump core
是否还为1
:
我们观察到:核心转储文件是很大的。
6.3 核心转储的作用
当一个进程在出现异常的时候,操作系统会将进程在内存中的运行信息进行核心转储,转储到当前进程的运行目录下(磁盘),形成core.pid
这样的二进制大文件(核心转储文件)。
核心转储的作用是什么呢?
答案是:调试(事后调试),并且直接从出错的地方开始调试。
以下是调试样例代码
#include <iostream>using namespace std;int main()
{int a = 1;int b = 0;a = a / b;cout << "a = " << a << endl;return 0;
}
调试方法如下(四个步骤):
- 首先
gcc/g++
在编译时加-g
生成可调试文件
- 运行程序,生成 core-dump 文件
gdb 可执行文件
进入调试模式
- 在
gdb
命令行输入:core-file <核心转储文件>
。即利用核心转储文件,快速定位至出错的地方。
最后一个问题:既然核心转储文件这么好用,为什么大多数的云服务器默认是将它关闭的呢?
现在许多大型IT公司以及许多中小型企业,都倾向于使用云服务器来托管其后端服务和应用程序。如果打开的话,当应用程序如果收到某个信号,核心转储文件会在进程的当前目录下创建一个大文件。而有很多进程都可能会产生核心转储文件,当文件足够多时,磁盘被挤满,导致系统IO
异常,最终会导致整个服务器挂掉的,所以云服务器一般默认是关闭的。
相关文章:
![](https://i-blog.csdnimg.cn/direct/2d47b364e7d94c6f82cc59a8ba10a8ff.png)
【Linux】进程信号 --- 信号产生
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…...
![](https://www.ngui.cc/images/no-images.jpg)
Docker 容器中的 Docker Compose 简介
Docker Compose是什么 Docker Compose是一个用于定义和运行多个Docker容器的工具。它是Docker官方提供的开源项目,用于实现对Docker容器集群的快速编排。通过Compose,开发者可以使用YAML文件(通常是docker-compose.yml文件)来配置…...
![](https://www.ngui.cc/images/no-images.jpg)
手机日历如何与Outlook同步
有很多人和我一样遇到手机日历与Outlook同步问题,如新版outlook与小米日历的同步问题 - Microsoft Community,outlook账号无法在手机端自带的电子邮件App以exchange模式登录 - Microsoft Community,在安卓手机端无法电子邮件App以exchange模式…...
![](https://img-blog.csdnimg.cn/direct/709ae3d152dd4f018891cb4af1597b96.png)
python基础语法 007 文件操作-1读取写入
1 文件操作 1.1 什么时候用文件操作? 打开文档写东西看东西拿文档做统计 在python 文档操作作用 存储数据读取数据 打开文件有什么用? 读取数据,写入数据不管什么数据都可以用open打开,如可复制一张图片 1.2 open() 读取,…...
![](https://i-blog.csdnimg.cn/direct/7dfd3330aec14e1fb1914ce56c295a98.webp)
C语言·函数(超详细系列·全面总结)
前言:Hello大家好😘,我是心跳sy,为了更好地形成一个学习c语言的体系,最近将会更新关于c语言语法基础的知识,今天更新一下函数的知识点,我们一起来看看吧! 目录 一、函数是什么 &a…...
![](https://i-blog.csdnimg.cn/direct/797afba09cf744b8a9f16d3e046d26a3.png)
Windows及Linux系统加固
君衍. 一、Windows加固1、配置简介2、账户配置3、本地配置4、安全设置 二、Linux加固1、配置简介2、网络配置3、日志和审计配置4、访问认证和授权配置5、系统运维配置 一、Windows加固 1、配置简介 通常在Windows安全配置中有两类对象 一类是Windows Server,如win …...
![](https://i-blog.csdnimg.cn/direct/585df72f29d44623b3bdbc5c3385251b.png)
Postman安装使用教程(详解)
目录 一、Postman是什么 二、安装系统要求 三、下载Postman 四、注册和登录Postman 五、创建工作空间 六、创建请求 一、Postman是什么 在安装之前,让我们先来简单了解一下Postman。Postman是一个流行的API开发工具,它提供了友好的用户界面用于发送…...
![](https://i-blog.csdnimg.cn/direct/2b45ca99b39549ed9716e7d209539e45.png)
【嵌入式开发之标准I/O】文件I/O的基本概念,打开、关闭、定位函数及实例
文件I/O和标准I/O 什么是文件I/O?什么是标准I/O? 文件I/O:文件I/O又称系统IO,系统调用,称之为不带缓存的IO(unbuffered I/O)。是操作系统提供的API接口函数。不带缓存指的是每个read,write都调用内核中的一个系统调…...
![](https://www.ngui.cc/images/no-images.jpg)
C++文件操作-文本文件-读文件
第一种 #include<iostream>//1、包含头文件 fstream #include<fstream> using namespace std;void test01() {//2、创建流对象ifstream ifs;//3、打开文件 并且判断是否打开成功ifs.open("test.txt", ios::in);if (!ifs.is_open()){cout << "…...
![](https://img-blog.csdnimg.cn/direct/7f06907c3c4b4c2a8800bace1e511bb8.gif#pic_center)
二叉树精选面试题
💎 欢迎大家互三:2的n次方_ 1. 相同的树 100. 相同的树 同时遍历两棵树 判断结构相同:也就是在遍历的过程中,如果有一个节点为null,另一棵树的节点不为null,那么结构就不相同 判断值相同:只需…...
![](https://img-blog.csdnimg.cn/img_convert/2a735ca5e0a04a3aca1a725fac41056d.jpeg)
如何在 Android 中删除和恢复照片
对于智能手机用户来说,相机几乎已经成为一种条件反射:你看到值得注意的东西,就拍下来,然后永远保留这段记忆。但如果那张照片不值得永远保留怎么办?众所周知,纸质快照拿在手里很难舍弃,而 Andro…...
![](https://www.ngui.cc/images/no-images.jpg)
HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(六)
一、仅支持一个静态块 规则:arkts-no-multiple-static-blocks 级别:错误 ArkTS不允许类中有多个静态块,如果存在多个静态块语句,请合并到一个静态块中。 TypeScript class C {static s: stringstatic {C.s aa}static {C.s C.s …...
![](https://i-blog.csdnimg.cn/direct/1af6cb722b61430abea7e6f85272a788.png)
功能测试与APPSCAN自动化测试结合的提高效率测试策略
背景 手工探索性测试(Manual Exploratory Testing,简称MET)是一种软件测试方法,它依赖于测试人员的直觉、经验和即兴发挥来探索应用程序或系统。与传统的脚本化测试相比,手工探索性测试不遵循固定的测试脚本࿰…...
![](https://i-blog.csdnimg.cn/direct/626c34a7106f4bbb99c434373a1ab2e6.png)
AVL树的理解和实现[C++]
文章目录 AVL树AVL树的规则或原理 AVL树的实现1.节点的定义2.功能和接口等的实现默认构造函数,析构函数拷贝构造函数插入搜索打印函数检查是否为平衡树,检查平衡因子旋转 AVL树 AVL树,全称Adelson-Velsky和Landis树,是一种自平衡…...
![](https://www.ngui.cc/images/no-images.jpg)
云计算遭遇的主要安全威胁
以下是详细说明云计算遭遇的所有主要安全威胁: 1. 数据泄露 描述:数据泄露是指未经授权的情况下访问和获取敏感数据。云计算环境中的数据泄露通常由于不安全的配置、软件漏洞或内部威胁造成。 案例: Capital One数据泄露:2019…...
![](https://i-blog.csdnimg.cn/direct/4a7e96cd8fb34e92ae4184d7f333b0ef.png)
[MySQL]02 存储引擎与索引,锁机制,SQL优化
Mysql存储引擎 可插拔式存储引擎 索引是在存储引擎底层上实现的 inno DB MySQL默认存储引擎: inno DB高可靠性和高性能的存储引擎 DML操作遵循ACID模型支持事务行级锁,提高并发访问性能支持外键 约束,保证数据完整性和可靠性 MySAM MySAM是MySQL的早期引擎 特点: 不支持事…...
![](https://www.ngui.cc/images/no-images.jpg)
ld,GNU 链接器介绍以及命令行参数详解
ld,GNU 链接器介绍以及命令行参数详解 当我们使用GCC编译源代码生成可执行程序,经过预处理、汇编、编译、链接四个阶段。 链接器(Linker)将多个目标文件和库文件链接起来,链接器还解决目标文件之间的符号引用ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
[web]-反序列化-base64
看到源码 <?php error_reporting(0); class A {public $contents "hello ctfer";function __toString(){if ((preg_match(/^[a-z]/i,$this->contents))) {system("echo $this->contents");return 111;}else{return "...";}} }functi…...
![](https://img-blog.csdnimg.cn/img_convert/7096e1f106be2e9f0579fb01660e0b58.jpeg)
【医学影像】RK3588+FPGA:满足远程诊疗系统8K音视频编解码及高效传输需求
医学影像 提供基于Intel平台、NXP平台、Rockchip平台的核心板、Mini-ITX主板、PICO-ITX主板以及工业整机等计算机硬件。产品板载内存,集成超高清编码/解码视频引擎,具有出色的数据处理能力和图形处理能力,功能高集成,可应用于超声…...
![](https://i-blog.csdnimg.cn/direct/69ee77b869574935b86a2a30dd41563a.png#pic_center)
昇思25天学习打卡营第16天|基于MindSpore通过GPT实现情感分类
文章目录 昇思MindSpore应用实践1、基于MindSpore通过GPT实现情感分类GPT 模型(Generative Pre-Training)简介imdb影评数据集情感分类 2、Tokenizer导入预训练好的GPT3、基于预训练的GPT微调实现情感分类 Reference 昇思MindSpore应用实践 本系列文章主…...
![](https://i-blog.csdnimg.cn/direct/4597a4f18f464522881e20cea6457130.png)
服务器借助笔记本热点WIFI上网
一、同一局域网环境 1、当前环境,已有交换机组网环境,服务器已配置IP信息。 设备ip服务器125.10.100.12交换机125.10.100.0/24笔记本125.10.100.39 2、拓扑图 #mermaid-svg-D4moqMym9i0eeRBm {font-family:"trebuchet ms",verdana,arial,sa…...
![](https://www.ngui.cc/images/no-images.jpg)
开发实战中Git的常用操作
Git基础操作 1.初始化仓库 git init解释:在当前目录中初始化一个新的Git仓库。 2.克隆远程仓库 git clone <repository-url>解释:从远程仓库克隆一个完整的Git仓库到本地。 3.检查当前状态 git status解释:查看当前工作目录的状态…...
![](https://i-blog.csdnimg.cn/direct/f1e85fbe95634583af0ffe002ce91830.png)
python调用chrome浏览器自动化如何选择元素
功能描述:在对话框输入文字,并发送。 注意: # 定位到多行文本输入框并输入内容。在selenium 4版本中,元素定位需要填写父元素和子元素名。 textarea driver.find_element(By.CSS_SELECTOR,textarea.el-textarea__inner) from …...
![](https://www.ngui.cc/images/no-images.jpg)
深入理解JS中的排序
在JavaScript开发中,排序是一项基础而重要的操作。本文将探讨JavaScript中几种常见的排序算法,包括它们的原理、实现方式以及适用场景。 1、冒泡排序 1.1、原理 通过比较相邻两个数的大小,交换位置排序:如果后一个数比前一个数小,则交换两个数的位置,重复这个过程,直…...
![](https://i-blog.csdnimg.cn/direct/027290ebb6a54e79a4d8e27275415d3e.png)
Kafka之存储设计
文章目录 1. 分区和副本的存储结构1. 分区和副本的分布2. 存储目录结构3. 文件描述 2. 相关配置3. 数据文件类型4. 数据定位原理LogSegment 类UnifiedLog 类 5. 副本数据同步HW水位线LEO末端偏移量HW更新原理 6. 数据清除 1. 分区和副本的存储结构 在一个多 broker 的 Kafka 集…...
![](https://www.ngui.cc/images/no-images.jpg)
Python面试整理-Python中的函数定义和调用
在Python中,函数是一种封装代码的方式,使得代码模块化和复用性更强。定义和调用函数是Python编程中的基本技能。以下是关于如何在Python中定义和调用函数的详细介绍: 函数定义 函数在Python中使用def关键字进行定义。函数体开始前,通常有一个可选的文档字符串(docstring)…...
![](https://i-blog.csdnimg.cn/direct/36567c4a89154d55990ad2c0ec392bb8.png)
HTTP协议、Wireshark抓包工具、json解析、天气爬虫
HTTP超文本传输协议 HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP 协议的重要特点: 一发一收…...
![](https://i-blog.csdnimg.cn/direct/8fe95432eef04591b6471d98f967863f.png#pic_center)
electron项目中实现视频下载保存到本地
第一种方式:用户自定义选择下载地址位置 渲染进程 // 渲染进程// 引入 import { ipcRenderer } from "electron";// 列表行数据下载视频操作,diffVideoUrl 是视频请求地址 handleDownloadClick(row) {if (!row.diffVideoUrl) {this.$message…...
![](https://i-blog.csdnimg.cn/direct/7d5890439ef44db199bbde18fac9100c.png)
基于chrome插件的企业应用
一、chrome插件技术介绍 1、chrome插件组件介绍 名称 职责 访问权限 DOM访问情况 popup 弹窗页面。即打开形式是通过点击在浏览器右上方的icon,一个弹窗的形式。 注: 展示维度 browser_action:所有页面 page_action:指定页面 可访问绝大部分api 不可以 bac…...
![](https://i-blog.csdnimg.cn/direct/ae8b0fcd512b4865bea93188194c05c5.png#pic_center)
unittest框架和pytest框架区别及示例
unittest框架和pytest框架区别及示例 类型unittest框架pytest框架unittest框架示例pytest框架示例安装python内置的一个单元测试框架,标准库,不需要安装第三方单元测试库,需要安装使用时直接引用 import unittest安装命令:pip3 install pyte…...
![](https://www.oschina.net/img/hot3.png)
cms官方网站/微信营销软件免费版
2019独角兽企业重金招聘Python工程师标准>>> 错误:500 OOPS: cannot change directory:/home/uftp 意思是:不能改变目录:/ home / uftp 原因:经过查看,发现并没有/ home / uftp这个目录 解决方案:修改该ftp…...
![](/images/no-images.jpg)
wordpress 关闭摘要/百度浏览器官网下载并安装
CAD看图王(CAD手机看图专业版)集快速看图、DWG画图、CAD批注、制图于一身的CAD看图软件,全球累计免费用户超过5000万。支持AutoCAD、浩辰CAD、天正建筑、酷家乐等国内外CAD图纸格式,图纸原生显示CAD图纸不失真。专业的fonts字体解析告别文字乱码…...
![](/images/no-images.jpg)
线下推广是做什么的/sem 优化软件
在Python中如何将给定字典拆分为键和值的列表?下面本篇文章就来给大家介绍几种实现方法,希望对大家有所帮助。【视频教程推荐:Python教程】方法一:使用内置函数:keys()和values()keys()函数:能以列表的形式…...
![](/images/no-images.jpg)
简单学校网站模板免费下载/百度网盘怎么用
62进制按这个排列:$dict 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;请高手写个函数 输入16进制,输出62进制,不要用高精度数学函数,服务器禁用了.回复讨论(解决方案)五一都出去玩了???$aide){$tmp$output[$index];$output[$index]$output[$aide];$ou…...
![](/images/no-images.jpg)
网站制作明细清单/百度关键词屏蔽
LumiSoft Mail Server是一个开源,免费的邮件服务器,能运行在.net/mono上,支持SMTP/POP3/IMAP4/WebMail,支持MS Sql Server/PostgreSql/Xml等数据存储方式.很适合中小型企业使用,稳定性和兼容性上都没什么问题。 1、基于Microsoft .Net2.0平台,系统更加稳定。2、提供…...
![](/images/no-images.jpg)
ps做游戏下载网站有哪些/合肥瑶海区房价
DdsDcpsCore.idl,定义了DCPS模块所需要的各种通讯报文(即DCPS层所需要的结构体),有助于了解和深入掌握DCPS层的含义。 DCPS以数据为中心的发布订阅层,共包含了16个idl文件,将分别列举和解释说明: DdsDcps.idlDdsDcpsConditionSeq.idlDdsDcpsCore.idlDdsDcpsDataReaderSe…...