Linux信号解析

在这里插入图片描述

文章目录

  • Linux信号概念
  • 信号种类
  • Linux信号产生
    • 异步
  • LInux信号阻塞
    • 递达、未决、阻塞、忽略
    • 信号集操作函数
    • 阻塞信号集操作函数
    • 未决信号集操作函数
  • Linux信号捕捉
    • signal函数
    • sigaction函数
  • 总结

Linux信号概念

信号在我们的生活中无处不在,常见的如电话铃声,闹钟等,这些的信号都是给我们传达某些信息,在接收到信息之后来选择采取什么样的措施,因此我们可以将信号理解为传达信息的事物。在Linux中也有这么一批信号,信号是操作系统提供的一种机制,用于通知进程发生了某种事件或异常情况。当特定的事件发生时(例如按下 Ctrl+C 来中断程序),操作系统会生成相应的信号,并将其发送给目标进程。总之,信号是操作系统提供的一种重要的进程间通信机制,操作系统捕获和分发信号,允许进程对信号进行响应和处理。

信号种类

Linux中有多种不同的信号,每个信号都有一个编号和一个宏定义名称,例如1表示SIGHUP,2表示SIGINT等等,这些宏定义可以在signal.h中找到。

在这里插入图片描述

在linux中也可以用kill -l命令来查看信号,以下信号可以分为两个主要类别:实时信号和标准信号。实时信号是为了满足实时应用程序的需求而引入的,具有较高的优先级和可预测的传递和处理时间。实时信号的信号编号通常在34到64之间,例如SIGRTMIN、SIGRTMIN+1等。它们具有实时信号队列,按照顺序接收和处理,以确保信号的顺序性。实时信号有两个优先级:实时信号和实时时钟信号。

标准信号是常规的信号类型,用于各种进程通信、控制和处理异常情况。标准信号的信号编号通常在1到31之间,包括SIGINT、SIGHUP、SIGTERM等。它们没有明确定义的优先级,信号处理通常较为基本。这两种信号类型都用于与进程通信、控制进程行为和处理各种事件。实时信号主要用于实时应用,而标准信号则更常用于一般用途的进程间通信和控制。

在这里插入图片描述

Linux信号产生

Linux信号可以通过多种方式产生,通常由内核、其他进程或硬件事件触发。例如进程终止或错误时也会产生信号进程执行发生错误时,如除以零,产生SIGFPE信号,进程访问未分配给它的内存或无效内存时,产生SIGSEGV信号。当用户在终端按下Ctrl+C会产生SIGINT信号。用户在终端按下Ctrl+\,产生SIGQUIT信号。用户按下Ctrl+Z,将进程置于后台并产生SIGTSTP信号。

在某些情况下,系统调用失败也会产生特定的信号,如SIGPIPE。这些信号产生方式可以由操作系统、应用程序或用户发起。处理这些信号可以通过注册信号处理函数来定义接收到信号时要执行的特定操作。例如可以使用kill命令向另一个进程发送信号。

在这里插入图片描述

此外还可以使用kill()函数向另一个进程发送信号,kill 函数通常用于终止一个进程。它是Unix和类Unix操作系统中的系统调用之一。

在这里插入图片描述

它的参数 pid代表的是要终止的进程的进程ID(PID)。sig表示要发送给目标进程的信号。通常,SIGTERM(15号信号)用于请求优雅地终止进程,而SIGKILL(9号信号)用于强制终止进程。

在这里插入图片描述

如果成功发送信号,则返回0。如果失败,则返回-1,并设置errno来指示错误的原因。如下代码:

void Usage(string str)
{cout << "Usage : \n\t";cout << str << "int sig   pid_t pid" << endl;
}int main(int argc, char *argv[])
{if(argc != 3){Usage(argv[0]);exit(1);}int signo = atoi(argv[1]);int target_id = atoi(argv[2]);int ret = kill(target_id, signo);  //给指定进程发送指定信号if(ret == -1){cout << errno << strerror(errno) << endl;}return 0;
}

这是一个简单的C++程序,用于给指定的进程发送信号。Usage 函数用于打印程序的用法说明,它接受一个字符串参数 str,用 cout 打印用法信息。main 函数首先检查命令行参数的数量,如果不等于3个(期望的参数数量),则调用 Usage 函数打印用法信息,并使用 exit(1) 终止程序。如果命令行参数数量正确,它将解析这两个参数为整数 signo 和 target_id,分别表示要发送的信号和目标进程的PID。然后,调用 kill 函数来向指定的进程发送指定的信号,并将返回值存储在 ret 变量中。最后,程序检查 kill 函数的返回值,如果返回值为-1,表示发送信号失败。它将使用 errno 和 strerror 函数来打印错误信息。结果如下:

在这里插入图片描述

异步

异步是指在程序执行过程中,某个操作可以独立于主程序流程,不阻塞主程序的执行,而在完成后通知主程序或回调执行相应的处理。简而言之,异步操作允许程序在等待某些事件完成的同时,可以继续执行其他任务。举例来说,假设你在下载一个大文件,如果是同步操作,程序会一直等待下载完成才能进行其他操作。而异步下载则会允许你在下载的同时执行其他任务,当下载完成时会通过回调或其他机制通知你。异步通常用于处理需要等待的操作,比如网络请求、文件读写、图形界面事件等。它可以提高程序的响应性和效率,因为在等待某些操作完成的同时,可以执行其他任务,充分利用了计算资源。

而信号相对于进程的控制流程来说就是异步的,因为对于进程来说,信号来源不确定,信号可以来自多种来源,包括其他进程、操作系统或硬件事件。进程无法预测何时会收到信号,因此无法像在同步控制流程中那样精确地安排信号的处理。并且信号可以随时中断进程,当进程正在执行某个任务时,随时可能收到信号。这个信号会中断进程当前的执行,转而执行与信号相关联的信号处理函数。这种中断式的行为使得信号处理是异步的,因为进程无法控制何时会被中断。信号处理被时间也是不确定的,信号处理函数的执行时间是不确定的,取决于信号的类型和处理函数的复杂性。进程无法预测信号处理将花费多长时间,因此无法以确定的方式管理信号的异步性质。

综上所述,可以说信号相对于进程的控制流程来说是异步,因为它们可以在进程不预期的时间中断进程的执行,且信号的来源和处理时间都是不确定的,无法由进程精确地控制。这使得处理信号的机制更加灵活,但也需要谨慎处理,以确保进程的稳定性和可靠性。

LInux信号阻塞

Linux中的信号阻塞是一种机制,它可以防止特定信号在某段代码执行期间被中断。这样可以确保关键部分的代码不会被信号中断,从而保证程序的一致性和可靠性。

递达、未决、阻塞、忽略

递达、未决、阻塞、忽略这些术语通常用于描述与信号处理相关的状态和操作:

  • 信号递达(Delivered):表示信号已经成功传递给目标进程,但目标进程尚未开始处理信号。信号已经到达进程的信号队列中,等待被处理。
  • 信号未决(Pending):未决状态表示信号已经递达,但目标进程还没有处理完该信号。在某些情况下,一个进程可以同时拥有多个未决信号,这些信号排队等待处理。
  • 信号阻塞(Blocked):阻塞表示进程已经将某些信号阻塞,即在信号掩码中将这些信号的位设置为1。阻塞信号的目的是防止它们在关键代码段执行期间中断进程。
  • 信号忽略(Ignored):忽略表示进程对特定信号的处理方式是忽略。当进程忽略信号时,该信号不会触发默认的操作或用户定义的信号处理函数,而会被静默忽略。

这些概念一起用于描述进程如何处理信号。例如,一个进程可以选择忽略某些信号,将其他信号阻塞以在关键部分执行时不被中断,然后处理已递达但未决的信号。递达和未决信号的状态告诉我们哪些信号已经到达,哪些正在等待被处理。信号处理是进程中管理这些状态的关键部分。

注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

信号集操作函数

在操作系统中,通常会有三张表与信号处理相关:阻塞表(Block Table)、未决表(Pending Table) 和 处理程序表(Handler Table)。这些表用于管理和描述进程的信号处理状态和方式。

block表维护了有关哪些信号被当前进程阻塞的信息,对于每个进程,内核会维护一个信号掩码,该掩码是一个位掩码,用于表示哪些信号被阻塞,哪些可以传递给进程。控制信号掩码可以通过系统调用如 sigprocmask 进行,使进程可以选择性地阻塞或解除阻塞信号。

pending表记录了哪些信号已经被递送给进程,但尚未被处理。每个进程都有一个未决信号集合,这些信号在被递送后保持未决状态,直到被处理。未决信号的状态可以在内核中进行管理,以确保每个信号都得到适当的处理。

handler表是一个数据结构,用于将信号与它们的处理方式(处理函数)相关联。对于每个信号,内核会维护一个处理程序表,记录了该信号的默认操作或用户自定义处理函数。当进程接收到一个信号时,内核会查找相应信号的处理程序表,并执行与之相关联的处理函数。

这三张表协同工作,允许进程管理信号的接收和处理。阻塞表控制哪些信号会被阻塞,未决表跟踪哪些信号等待处理,而处理程序表定义了每个信号的行为。这些机制使进程能够在异步情况下处理信号,以应对不同类型的事件和通信。

Linux中常规信号在递达之前产生多次的话只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里统计多次。

从这里就可以知道,每个信号只有一个 bit 的未决和阻塞标志,不是0就是1。因此在Linux中未决和阻塞标志可以用相同的数据类型sigset_t来存储。sigset_t 是一个数据类型,通常用于表示信号集合,用于管理和操作一组信号的状态。它是 POSIX 标准中定义的一种数据类型,用于在信号处理中指定和操作一组信号。sigset_t 通常是一个用于存储信号掩码的数据结构。信号掩码是一个位掩码,其中每一位对应一个特定的信号。如果某个信号的位被设置为 1,表示该信号被阻塞;如果为 0,表示该信号可以传递给进程。通过设置和修改 sigset_t 对象,可以实现对信号的阻塞和解除阻塞。以下是一些与 sigset_t 相关的常用函数和操作:

在这里插入图片描述

  • sigemptyset(sigset_t *set):用于初始化一个空的信号集合,即将所有信号位都设置为 0。
  • sigfillset(sigset_t *set):用于将一个信号集合设置为包含所有可能的信号,即将所有信号位都设置为 1。
  • sigaddset(sigset_t *set, int signum):用于将指定信号添加到信号集合中,将对应信号位设置为 1。
  • sigdelset(sigset_t *set, int signum):用于从信号集合中移除指定信号,将对应信号位设置为 0。
  • sigismember(const sigset_t *set, int signum):用于检查指定信号是否包含在信号集合中。

在这里插入图片描述

sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。其他四个函数都是成功返回0,出错返回-1。sigset_t 对象通常在信号处理函数中使用,以防止在关键代码段执行时被特定信号中断。通过操作 sigset_t 对象,可以实现对信号的精细控制和管理。

阻塞信号集操作函数

对于进程的阻塞信号集可以调用函数sigprocmask来读取或更改,sigprocmask 是一个 POSIX 标准定义的系统调用,该系统调用的函数原型如下:

在这里插入图片描述
其中 how 参数指定了如何修改信号屏蔽字,有以下3种选择:

  • SIG_BLOCK:将 set 中的信号添加到当前的信号屏蔽字中。
  • SIG_UNBLOCK:从当前的信号屏蔽字中移除 set 中的信号。
  • SIG_SETMASK:将当前的信号屏蔽字设置为 set 中的值。

set 参数和 oldset 参数都是一个指向 sigset_t 类型的指针,set 参数包含了要设置的新的信号屏蔽字。oldset 参数用于存储调用 sigprocmask 前的信号屏蔽字。如果不关心原始的信号屏蔽字,可以将 oldset 设为 NULL。

未决信号集操作函数

对于进程的未决信号集可以用 sigpending 函数来查看,sigpending 是一个 POSIX 标准定义的函数,用于检索当前进程中的未决信号,函数原型如下:

在这里插入图片描述
set 参数是一个指向 sigset_t 类型的指针,用于存储检测到的未决信号。这个函数会将当前进程中的未决信号的信号集合存储到 set 中。sigpending 函数通常在信号处理程序中使用,以确定哪些信号在当前上下文中已经到达但尚未被处理。未决信号的检查可以帮助进程采取相应的行动来处理这些信号,比如选择性地解除信号阻塞、执行相应的处理程序等。

未决信号是在 sigpending 函数被调用时确定的,因此在函数返回后,仍然可能会有新的信号到达并成为未决信号。

Linux信号捕捉

Linux的信号产生之后,就需要有东西能接收到这个信号,然后在决定接收到这个信号后采取什么样的措施。如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。

signal函数

在Linux中,可以通过注册信号处理函数来捕捉信号,以定义在接收到特定信号时要执行的操作。其中就可以使用signal()函数来对信号进行捕捉处理,signal()函数是用于在Linux和UNIX系统中注册信号处理函数的函数之一,它的原型如下:

在这里插入图片描述

signal()函数的主要作用是告诉操作系统,在接收到特定信号(由signum指定)时,去调用特定的信号处理函数(由handler指定)。这个函数返回一个函数指针,该指针指向以前注册的信号处理函数(通常是默认处理方式)。一般你可以忽略这个返回值,但如果需要以后恢复默认的信号处理行为的话就可以使用它。如下代码:

int main()
{while(1){cout << "run......." << endl;sleep(1);}return 0;
}

代码是一个死循环,当我们按下Ctrl + C的时候进程会收到一个2号信号SIGINT从而结束进程。

在这里插入图片描述
但是当使用signal函数对2号信号进行自定义捕捉时,这时候再去按下Ctrl + C就不再是执行默认动作结束进程,而是去执行我们的自定义动作,如下代码:

void handler(int signo)
{cout << "get signo : " << signo << endl;
}int main()
{signal(2, handler);while(1){cout << "run......." << endl;sleep(1);}return 0;
}

在这段代码中,当按下Ctrl + C发送2号信号时,程序会去执行handler方法并打印出捕捉到的信号。

在这里插入图片描述

sigaction函数

sigaction 是一个 POSIX 系统调用,用于检查或修改进程的信号处理行为。与 signal 函数相比,sigaction 提供了更完整和灵活的控制机制来管理信号处理。以下是 sigaction 的函数原型:
在这里插入图片描述
其中参数 signum表示指定要操作的信号。act 是一个指向 struct sigaction 的指针,该结构描述了新的信号处理行为。参数 oldact 是一个指向 struct sigaction 的指针,用于保存之前的信号处理行为。如果不关心之前的行为,可以设置为 NULL。

在这里插入图片描述

struct sigaction 结构包含以下主要字段:

  • sa_handler:指向信号处理函数的指针。
  • sa_sigaction:用于更高级的信号处理,并提供关于信号的更多信息。
  • sa_mask:在处理该信号时要阻塞的其他信号集合。
  • sa_flags:用于指定各种信号处理选项。
  • sa_restorer:此字段已不再使用,但在一些旧的系统中仍然存在。

在这里插入图片描述

sa_flags 可能包括以下选项之一或多个:

  • SA_NOCLDSTOP:如果信号是 SIGCHLD,则在子进程停止或继续时不会产生该信号。
  • SA_NOCLDWAIT:使父进程在其子进程终止时不创建僵尸进程。
  • SA_NODEFER:不将处理的信号自动添加到信号掩码中。
  • SA_ONSTACK:使用为信号专门定义的备用堆栈,如果有的话。
  • SA_RESETHAND:在信号处理程序被调用后,将信号的处理程序重置为默认值。
  • SA_RESTART:使某些被信号中断的系统调用重新启动。
  • SA_SIGINFO:指示信号处理程序应该使用 sa_sigaction 字段而不是 sa_handler。

总的来说,sigaction 提供了一个强大的机制来查看和更改信号处理行为。由于它提供了对信号处理的详细控制,所以它通常被推荐为设置信号处理程序的首选方法。如下代码:

void sighandler(int signo)
{cout << "get signo : " << signo << endl;
}
int main()
{struct sigaction act, oldact;memset(&act, 0, sizeof(act));memset(&oldact, 0, sizeof(oldact));act.sa_handler = sighandler;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask, 2);sigaddset(&act.sa_mask, 3);sigaction(2, &act, &oldact);sigaction(3, &act, &oldact);while(1){cout << "PID : " << getpid() << endl;sleep(1);}return 0;
}

这段代码设置了信号处理函数 sighandler,然后通过 sigaction 函数为信号2和信号3分别设置了新的信号处理方式,同时设置了信号屏蔽集,以确保在处理这些信号时不会被其他信号中断。然后,程序进入无限循环,输出PID,并持续运行,等待信号的触发。当信号2或3被触发时,将会调用 sighandler 函数来处理它们。
在这里插入图片描述

总结

文章中介绍了Linux中信号的概念、信号的种类以及信号的产生方式进行分析,并对Linux信号的阻塞和捕捉函数进行分析,对函数的参数逐一分析,并提供示例代码供参考。总之,Linux信号是一种重要的进程通信机制,允许进程之间以及操作系统与进程之间进行异步通信,以响应各种事件和异常情况。了解如何正确使用和处理信号对于编写可靠的Linux应用程序至关重要。

码文不易,客官如果觉得文章对你有帮助的话就来一个三连吧👍。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国庆10.4

QT实现TCP服务器客户端 服务器 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket> //客户端头文件 #include <QList> //链表容器 #include <QMe…

【C 语言进阶(12)】动态内存管理笔试题

文章目录 题目 1题目 2题目 3题目 4 题目 1 运行 Test 函数后的结果是什么&#xff1f; void GetMemory(char* p) {p (char*)malloc(100); }void Test(void) {char* str NULL;GetMemory(str);strcpy(str, "hello world");printf(str); }代码结果 程序崩溃。 代…

C++ YAML使用

C++工程如何使用YAML-cpp 一、前期准备工作 1、已安装minGW、cmake、make等本地工具。 2、下载YAML-cpp第三方开源代码(一定要下载最新的release版本,不然坑很多)。 3、生成YAML-cpp静态库 (1)在yaml-cpp-master下建立build文件夹; (2)在该文件夹下生成MakaFile文…

C++入门-day01

一、认识C C融合了三种不同的编程方式 C代表的过程性语言在C基础上添加的类、结构体puls代表的面向对象语言C模板支持泛型编程 C完全兼容C的特性 Tips&#xff1a;侯捷老师提倡的Modren C是指C11、C14、C17和C20这些新标准所引入的一系列新特性和改进。在我们练习的时候也应当去…

Blender 之创建一个简单的笔筒

文章目录 成品图实现步骤 你是不是想创建一个笔筒捏&#xff1f; follow me! 成品图 实现步骤 先添加一个柱体 选中柱体&#xff0c;然后按tab 进入编辑模式 切换到面模式 &#xff08;可以按主键盘的 3 键&#xff09; 分别选中上下面&#xff0c;鼠标右键&#xff0c;选…

BL808学习日志-2-LVGL for M0 and D0

一、lvgl测试环境 对拿到的M1S_DOCK开发板进行开发板测试&#xff0c;博流的官方SDK是支持M0和D0两个内核都进行测试的&#xff1b;但是目前只实现了M0的LVGLBenchmark&#xff0c;测试D0内核中发现很多莫名其妙的问题。一会详细记录。 使用的是开发板自带的SPI显示屏&#xff…

【软考】4.2 关系代数/函数依赖/范式

《 关系代数 》 表和表之间的逻辑运算 笛卡尔积&#xff1a;S1 x S2 投影&#xff1a;π&#xff1b;选择某一列&#xff08;属性&#xff09;&#xff1b;一个关系R的投影操作结果也是一个关系&#xff0c;记作Πa&#xff0c;它由从关系R中选出的A列元素构成&#xff1b;选择…

隐私交易成新刚需,Unijoin 凭什么优势杀出重围?

随着区块链技术的普及和发展&#xff0c;全球加密货币用户在持续增长&#xff0c;根据火币研究院公布的数据&#xff0c;2022年全球加密用户已达到 3.2亿人&#xff0c;目前全球人口总数超过了 80亿&#xff0c;加密货币用户渗透率已达到了 4%。 尤其是在 2020 年开启的 DeFi 牛…

机器学习7:逻辑回归

一、说明 逻辑回归模型是处理分类问题的最常见机器学习模型之一。二项式逻辑回归只是逻辑回归模型的一种类型。它指的是两个变量的分类&#xff0c;其中概率用于确定二元结果&#xff0c;因此“二项式”中的“bi”。结果为真或假 — 0 或 1。 二项式逻辑回归的一个例子是预测人…

《Python趣味工具》——ppt的操作(刷题版)

前面我们对PPT进行了一定的操作&#xff0c;并将其中的文字提取到了word文档中。现在就让我们来刷几道题巩固巩固吧&#xff01; 文章目录 1. 查看PPT&#xff08;上&#xff09;2. 查看PPT&#xff08;中&#xff09;3. 查看PPT&#xff08;下&#xff09;4. PPT的页码5. 大学…

手机自动直播系统源码交付与代理加盟注意事项解析!

随着直播行业的不断发展&#xff0c;手机自动直播已经成为了人们生活中不可或缺的一部分。手机无人直播软件成了香饽饽&#xff0c;各类手机实景直播APP大批量涌现。因为创业和技术门槛低&#xff0c;市场需求高&#xff0c;所以成了最火热创业赛道。那么如果是不懂技术的人群&…

5.Vectors Transformation Rules

在上节&#xff0c;有个问题&#xff1a;向量分量的转换方式 与 新旧基底的转换方式相反 用例子来感受一下&#xff0c; 空间中一向量V&#xff0c;即该空间的一个基底&#xff1a;e1、e2 v e1 e2 现把基底 e1 、 e2 放大两倍。变成 基向量放大了两倍&#xff0c; 但对于…

Java8 Lambda.stream.sorted() 方法使用浅析分享

文章目录 Java8 Lambda.stream.sorted() 方法使用浅析分享sorted() 重载方法一升序降序 sorted() 重载方法二升序降序多字段排序 mock代码 Java8 Lambda.stream.sorted() 方法使用浅析分享 本文主要分享运用 Java8 中的 Lambda.stream.sorted方法排序的使用&#xff01; sorted…

速看:免费领取4台阿里云服务器_申请入口及领取流程

注册阿里云账号&#xff0c;免费领云服务器&#xff0c;最高领取4台云服务器&#xff0c;每月750小时&#xff0c;3个月免费试用时长&#xff0c;可快速搭建网站/小程序&#xff0c;部署开发环境&#xff0c;开发多种企业应用。阿里云服务器网分享阿里云服务器免费领取入口、免…

机器学习必修课 - 如何处理缺失数据

运行环境&#xff1a;Google Colab 处理缺失数据可简单分为两种方法&#xff1a;1. 删除具有缺失值的列 2. 填充 !git clone https://github.com/JeffereyWu/Housing-prices-data.git下载数据集 import pandas as pd from sklearn.model_selection import train_test_split导…

python中使用matplotlib绘图

一、背景 当我们在写python程序时&#xff0c;不可避免的需要将数据可视化&#xff0c;也就是绘制出数据的曲线图&#xff0c;以便我们更直观的观察数据间的变化&#xff0c;和方便对比。此时就要用到matplotlib库了。 matplotlib官方给出的定义是&#xff1a; 翻译过来也就是…

集合原理简记

HashMap 无论在构造函数是否指定数组长度&#xff0c;进行的都是延迟初始化 构造函数作用&#xff1a; 阈值&#xff1a;threshold&#xff0c;每次<<1 &#xff0c;数组长度 负载因子 无参构造&#xff1a;设置默认的负载因子 有参&#xff1a;可以指定初始容量或…

计组——I/O方式

一、程序查询方式 CPU不断轮询检查I/O控制器中“状态寄存器”&#xff0c;检测到状态为“已完成”之后&#xff0c;再从数据寄存器取出输入数据。 过程&#xff1a; 1.CPU执行初始化程序&#xff0c;并预置传送参数&#xff1b;设置计数器、设置数据首地址。 2. 向I/O接口发…

计算机竞赛 目标检测-行人车辆检测流量计数

文章目录 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 行人车辆目标检测计数系统 …

HTTP的请求方法,空行,body,介绍请求报头的内部以及粘包问题

目录 一、GET与POST简介 二、空行和body 三、初识请求报头以及粘包问题 四、认识请求报头剩余部分 一、GET与POST简介 GET https://www.sogou.com/HTTP/1.1 请求报文中的方法&#xff0c;是最常规的方法&#xff08;获取资源&#xff09; POST&#xff1a;传输实体主体的方法…