Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示
项目场景:
项目需求,需要做一个基于边缘端的人脸识别远程监控摄像头并在网页前端展示 ,这里采用国产香橙派作为边缘计算终端,安装ubuntu系统,系统中采用v4l2接口对摄像头进行获取,当客户端通过网页进行请求时,服务器通过http服务的形式将一帧帧图像发送给客户端,只要一秒钟能够传送25帧左右,展示效果就是在网页端播放视频:
问题描述1
怎样从摄像头里面获取帧数据,这里我们将USB摄像头连接在开发板上:

可以看到,确实是有video0这个摄像头,该摄像头就是外接的USB摄像头
解决方案1:
采用V4L2接口通过中断将内核状态读取到的数据映射到用户空间:
以下代码是将内核空间与用户空间进行映射
for(int i = 0; i <4;i++) {mapbuffer.index = i;ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer); //从内核空间中查询一个空间作映射if (ret < 0){perror("查询内核空间失败");}//映射到用户空间mptr[i] = (unsigned char *)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);size[i] = mapbuffer.length; //保存映射长度用于后期释放//查询后通知内核已经放回ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer);if (ret < 0){perror("放回失败");}}
以下代码是通过中断获取内核态的数据,并在用户态对数据进行内存拷贝,即将数据拷贝到数组,方便其他线程进行数据处理和数据展示
struct v4l2_buffer readbuffer;readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //每个结构体都需要设置type为这个参赛要记住ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer);int read_len = mapbuffer.length;int send_len = 1024;//printf("%d \n",read_len);if (ret < 0){perror("读取数据失败");}if(1){void *ptr = mptr[readbuffer.index];memcpy(jpg_buff, ptr, readbuffer.length);
}
问题描述2
在网页前端播放视频,首先视频是一帧帧图像组成的,这里我们每间隔一个短时间就发送一帧,同时http 客户端和服务端采用keep-live长连接形式。为了加快速度,这里我采用了两个线程,现成1读取视频,并将图像帧放在一个公共数组中,线程2将公共数组中的数据通过tcp传输发送给客户端。
同时,线程1和线程之间采用的是条件变量进行同步
解决方案2:
多线程共享全局变量加快视频读取速度和图像发送速度:
线程1
pthread_mutex_lock(&lock);void *ptr = mptr[readbuffer.index];memcpy(jpg_buff, ptr, readbuffer.length);//将读取到的图像拷贝到字符数组 pthread_mutex_unlock(&lock);pthread_cond_signal(&hasNode);
线程2
pthread_cond_wait(&hasNode,&lock);
void *ppptr = jpg_buff;
pthread_mutex_unlock(&lock);
这里的jpg_buff是共享全局数组
问题描述3
网页长连接设置问题:
服务器端在返回报文头时,加上
"Content-Type:multipart/x-mixed-replace;
即表示当前连接是基于长连接
解决方案:
提示:这里填写该问题的具体解决方案:
下面是报文头的内容
/*
HTTP长连接处理客户端请求
"HTTP/1.0 200 OK\r\n"
"Server: wbyq\r\n"
"Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n"
"\r\n"
"--boundarydonotcross\r\n"
*/
这是程序运行时的效果图:
需要在与开发板同一个局域网的终端上网址中键入:192.168.0.105:8080
其中192.168.0.105是开发板的ip地址

最后附上总代码
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <assert.h>
#include <fcntl.h>
#include <jpeglib.h>
#include <linux/fb.h>
#include <linux/videodev2.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <pthread.h>
#include "sd_usb_pic.h"
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h> /* See NOTES */
#include <unistd.h>
#include <sys/time.h>#define HTTP_PORT 8080 //HTTP服务器端口号
pthread_mutex_t mutex;
pthread_cond_t hasNode = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
char jpg_buff[614400]; //保存从USB摄像头读取的图像矩阵
int send_html_cnt = 0 ;
/*
服务端响应客户端请求"HTTP/1.1 200 OK\r\n"
"Content-type:image/jpeg\r\n"
"Content-Length:1234\r\n"
"\r\n"形参:c_fd --客户端套接字type --文件类型file --要发送的文件
返回值:0成功,其它失败
*/
void *ppp_tr = NULL;
int fd_fb;
static struct fb_var_screeninfo var; /* LCD可变参数 */
static unsigned int *fb_base = NULL; /* Framebuffer映射基地址 */
int lcd_w = 800 ,lcd_h= 480; //定义显示器分辨率/*
形参:c_fd --客户端套接字type --文件类型file --要发送的文件
返回值:0成功,其它失败
*/
int Http_SendData(int c_fd,const char *type,const char *file)
{int fd=open(file,O_RDONLY);//打开文件if(fd<0)return -1;//打开文件失败struct stat statbuf;fstat(fd,&statbuf);if(statbuf.st_size<=0){close(fd);return -2;}char buff[1024]={0};snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n""Content-type:%s\r\n""Content-Length:%ld\r\n""\r\n",type,statbuf.st_size);if(write(c_fd,buff,strlen(buff))!=strlen(buff)){close(fd);return -3;//发送数据头失败}/*发送文件内容*/int size;while(1){size=read(fd,buff,sizeof(buff));if(write(c_fd,buff,size)!=size)break;//发送失败if(size!=sizeof(buff))break;//发送完成}close(fd);return 0;
}int Http_SendPic(int c_fd,const char *type,const char *file)
{char buff[1024]={0};snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n""Content-type:%s\r\n""Content-Length:%ld\r\n""\r\n",type,614400);if(write(c_fd,buff,strlen(buff))!=strlen(buff)){return -3;//发送数据头失败}/*发送文件内容*/int size;int cnt = 0 ; pthread_mutex_lock(&mutex);void *ppptr = jpg_buff;while(1){int size= 1024;int wt_len = write(c_fd,ppptr,size);//发送失败cnt += wt_len ; ppptr += wt_len ; if(cnt >= 614400 ) {break;}//发送完成}pthread_mutex_unlock(&mutex);return 0;
}int Http_SendPic1(int c_fd,const char *type,const char *file)
{char buff[1024]={0};snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n""Server:LiMeng \r\n""Content-type:image/jpeg\r\n""Content-Length:%ld\r\n""\r\n",614400);if(write(c_fd,buff,strlen(buff))!=strlen(buff)){return -3;//发送数据头失败}/*发送文件内容*/int size;int cnt = 0 ; pthread_mutex_lock(&mutex);void *ppptr = jpg_buff;while(1){int size= 1024;int wt_len = write(c_fd,ppptr,size);//发送失败cnt += wt_len ; ppptr += wt_len ; if(cnt >= 614400 ) {break;}//发送完成}pthread_mutex_unlock(&mutex);return 0;
}/*
HTTP长连接处理客户端请求
"HTTP/1.0 200 OK\r\n"
"Server: wbyq\r\n"
"Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n"
"\r\n"
"--boundarydonotcross\r\n"
*/int Http_Content(int c_fd)
{char buff[1024]={0};/*建立长连接*/snprintf(buff,sizeof(buff),"HTTP/1.0 200 OK\r\n""Server: wbyq\r\n""Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n""\r\n""--boundarydonotcross\r\n");if(write(c_fd,buff,strlen(buff))!=strlen(buff))return -1;//发送报文头失败int jpe_image_size = 614400;//保存jpeg图像大小//int send_html_cnt = 0 ;clock_t t1;t1 = clock();char save_name[10];int save_idx = 0 ;struct timeval start_time, end_time;while(1){//auto beg = clock();t1 = clock();pthread_cond_wait(&hasNode,&lock);//printf("wait time is %d us \n", (clock() - t1) ); auto beg = clock();gettimeofday(&start_time, NULL);/*(1)响应报文头"Content-type:image/jpeg\r\n""Content-Length:666\r\n""\r\n"*/snprintf(buff,sizeof(buff), "Content-type:image/jpeg\r\n""Content-Length:%d\r\n""\r\n",jpe_image_size);if(write(c_fd,buff,strlen(buff))!=strlen(buff)){return -2;//响应报文头失败}/*发送jpg图像数据*///pthread_mutex_lock(&mutex);//互斥锁上锁//pthread_cond_wait(&hasNode,&lock);void *ppptr = jpg_buff;//void *ppptr = ppp_tr;//sprintf(save_name,"my_%d.jpg",save_idx++);//FILE *file=fopen(save_name, "w");//fwrite(ppptr , 614400, 1,file);//close(file);int cnt = 0 ; while(1){int size= 1024 * 600;//int size= 1024 ;int wt_len = write(c_fd,ppptr,size);//发送失败cnt += wt_len ; ppptr += wt_len ; if(cnt >= 614400 ) {break;}//发送完成} //pthread_mutex_unlock(&mutex);//互斥锁上锁//pthread_mutex_unlock(&lock);//sleep(20);/*(3)发送间隔字符串"\r\n""--boundarydonotcross\r\n"*/strcpy(buff,"\r\n--boundarydonotcross\r\n");if(write(c_fd,buff,strlen(buff))!=strlen(buff)){break;//发送间隔符失败}auto end = clock();gettimeofday(&end_time, NULL);double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;//printf("sendtime is %d us \n", (end - beg) ); //printf("send cnt is %d us \n", send_html_cnt ); send_html_cnt++;//pthread_mutex_unlock(&lock);//usleep(40000);//auto beg = clock();//printf("sendtime is %d ms \n", (end - beg) ); printf("sendtime is %d ms \n", timeuse ); pthread_mutex_unlock(&lock);usleep(1);}return -4;//发送图像数据失败
}/*线程工作函数*/
void *pth_work(void *arg)
{int c_fd=*(int *)arg;free(arg);char buff[1024]={0};int size;size=read(c_fd,buff,sizeof(buff)-1);if(size<=0){close(c_fd);pthread_exit(NULL);}buff[size]='\0';printf("buff=%s\n",buff);if(strstr(buff,"GET / HTTP/1.1"))//请求网页文件{Http_SendData(c_fd,"text/html","./html/image.html");}else if(strstr(buff,"GET /1.bmp HTTP/1.1")){Http_SendData(c_fd,"application/x-bmp","./html/1.bmp");}else if(strstr(buff,"GET /my.jpg HTTP/1.1")){//Http_SendData(c_fd,"application/x-jpg","./html/my.jpg");//Http_SendPic(c_fd,"application/x-jpg","./html/my.jpg");Http_Content(c_fd);}else if(strstr(buff,"GET /my_32.jpg HTTP/1.1")){Http_SendData(c_fd,"application/x-bmp","./html/my_32.jpg");}else if(strstr(buff,"GET /100.bmp HTTP/1.1")){Http_SendData(c_fd,"application/x-bmp","./html/100.bmp");}else if(strstr(buff,"GET /favicon.ico HTTP/1.1")){Http_SendData(c_fd,"image/x-icon","./html/wmp.ico");}else{Http_SendData(c_fd,"application/x-jpg","./html/limeng.jpg");//Http_SendData(c_fd,"application/x-bmp","./html/my.jpg");}close(c_fd);//printf("22222222222222222222222 \n");pthread_exit(NULL);
}int generate_pic()
{int fd = open("/dev/video0",O_RDWR); //打开摄像头设备if (fd < 0){perror("打开设备失败");return -1;}struct v4l2_format vfmt;vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //摄像头采集vfmt.fmt.pix.width = 640; //设置摄像头采集参数,不可以任意设置vfmt.fmt.pix.height = 480;vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //设置视频采集格式为mjpg格式int ret = ioctl(fd,VIDIOC_S_FMT,&vfmt);if (ret < 0){perror("设置格式失败1");}//申请内核空间struct v4l2_requestbuffers reqbuffer;reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;reqbuffer.count = 4; //申请4个缓冲区reqbuffer.memory = V4L2_MEMORY_MMAP; //映射方式ret = ioctl(fd,VIDIOC_REQBUFS,&reqbuffer);if (ret < 0){perror("申请空间失败");}//映射unsigned char *mptr[4];//保存映射后用户空间的首地址unsigned int size[4];struct v4l2_buffer mapbuffer;//初始化type和indexmapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;for(int i = 0; i <4;i++) {mapbuffer.index = i;ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer); //从内核空间中查询一个空间作映射if (ret < 0){perror("查询内核空间失败");}//映射到用户空间mptr[i] = (unsigned char *)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);size[i] = mapbuffer.length; //保存映射长度用于后期释放//查询后通知内核已经放回ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer); if (ret < 0){perror("放回失败");}}//开始采集int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;ret = ioctl(fd,VIDIOC_STREAMON,&type); if (ret < 0){ perror("开启失败");}//定义一个空间存储解码后的rgbint sum = 0;//这里是用来控制读取的帧的数量 实际场景下 可以不要这个限制int read_cnt = 0 ;//记录读取图像线程char save_name[10];int save_idx = 0 ;struct timeval start_time, end_time;while(1){struct v4l2_buffer readbuffer;readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //每个结构体都需要设置type为这个参赛要记住ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer); int read_len = mapbuffer.length;int send_len = 1024;//printf("%d \n",read_len);if (ret < 0){perror("读取数据失败");}if(1){//void *ptr = mptr[readbuffer.index];//pthread_mutex_lock(&mutex);//gettimeofday(&start_time, NULL);pthread_mutex_lock(&lock);void *ptr = mptr[readbuffer.index];///ppp_tr = mptr[readbuffer.index];//auto beg = clock();//printf("read frame %d \n",beg);//printf("read frame %d %d %d \n",read_cnt++,send_html_cnt,beg);//pthread_mutex_lock(&mutex);memcpy(jpg_buff, ptr, readbuffer.length);//将读取到的图像拷贝到字符数组//ppp_tr = ptr ; //auto end = clock();//gettimeofday(&end_time, NULL);//double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;sprintf(save_name,"my_%d.jpg",save_idx++);//int fd = open(save_name, O_CREAT |O_WRONLY|O_TRUNC,0666);//char buf[1024*600]={0};//FILE *file=fopen(save_name, "w");//fwrite(mptr[readbuffer.index] , readbuffer.length, 1,file);//fwrite(ptr , readbuffer.length, 1,file);//close(file);//write(fd,buf,1024 * 600);//close(fd);pthread_mutex_unlock(&lock);pthread_cond_signal(&hasNode);//gettimeofday(&end_time, NULL);//pthread_mutex_unlock(&mutex);auto end = clock();//printf("runtime is %f \n", (end - beg) / CLOCKS_PER_SEC ); //printf("runtime is %f \n", (end - beg) ); printf("runtime is %d ms \n", timeuse ); //sleep(20);usleep(1);}//通知内核使用完毕ret = ioctl(fd, VIDIOC_QBUF, &readbuffer);if(ret < 0){perror("放回队列失败");}}//停止采集ret = ioctl(fd,VIDIOC_STREAMOFF,&type);//释放映射for(int i=0; i<4; i)munmap(mptr[i], size[i]);close(fd); //关闭文件return 0;err1:close(fd_fb);return -1;
}void shuijiao()
{struct timeval start_time, end_time;while(1){gettimeofday(&start_time, NULL);pthread_cond_wait(&hasNode,&lock);usleep(10000);pthread_mutex_unlock(&lock);gettimeofday(&end_time, NULL);double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;//printf("shuijiao time is %f ms \n", timeuse * 1000 );}
}int main()
{int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){printf("创建网络套接字失败\n");return 0;}/*允许绑定已使用的端口号*/int on = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));/*绑定端口号*/struct sockaddr_in s_addr={.sin_family=AF_INET,//IPV4.sin_port=htons(HTTP_PORT),.sin_addr.s_addr=INADDR_ANY};if(bind(sockfd,(const struct sockaddr *)&s_addr,sizeof(s_addr))){printf("绑定端口号失败\n");return 0;}/*设置监听数量*/listen(sockfd,100);/*等待客户端连接*/struct sockaddr_in c_addr;socklen_t len=sizeof(c_addr);int c_fd;pthread_t pthid;int *p=NULL;pthread_t pthid1;pthread_create(&pthid1,NULL,generate_pic,NULL);pthread_detach(pthid1);//设置为分离属性//shuijiao();//while(1){shuijiao();}while(1){c_fd=accept(sockfd,(struct sockaddr *)&c_addr,&len);if(c_fd==-1){printf("客户端连接失败\n");continue;}printf("套接字 : %d 连接成功,%s:%d\n",c_fd,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));p=malloc(4);*p=c_fd;pthread_create(&pthid,NULL,pth_work,p);pthread_detach(pthid);//设置为分离属性}
}
代码的编译命令是
gcc serv.c -o serv -ljpeg
相关文章:
Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示
项目场景: 项目需求,需要做一个基于边缘端的人脸识别远程监控摄像头并在网页前端展示 ,这里采用国产香橙派作为边缘计算终端,安装ubuntu系统,系统中采用v4l2接口对摄像头进行获取,当客户端通过网页进行请求…...
《编码——隐匿在计算机软硬件背后的语言》精炼——第15-16章(十六进制,RAM)
“学习如春起之苗,不见其增,日有所长。” —— 宋代朱熹 文章目录 十六进制十六进制概述十六进制表字节到十六进制 存储器特定的读功能特定的写功能RAM大型RAM阵列 十六进制 十六进制概述 十六进制是一种适用于计算机的进制法。在十进制中,…...
leetcode.1376 通知所有员工所需的时间 - bfs/dfs + 树
1376. 通知所有员工所需的时间 目录 一、bfs 二、dfs 题目: 公司里有 n 名员工,每个员工的 ID 都是独一无二的,编号从 0 到 n - 1。公司的总负责人通过 headID 进行标识。在 manager 数组中,每个员工都有一个直属负责人&#x…...
AtCoder Beginner Contest 300——A-G题讲解
蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提! Hello, 大家好哇!本初中生蒟蒻讲解一下AtCoder Beginner Contest 300这场比赛的A-G题! A - N-choice question 原题 Problem Statement Given integers A A A and…...
Go:值与指针
1. 计算机中的值 在百万年的演化历史中,人类对事物的属性进行了抽象,有了数量、精度、信息等概念的表示,对应的我们称之为整数、小数、文本文字等。计算机出现后,我们使用计算机对真实世界的问题进行建模,通过计算机的…...
【Linux】进程学习(2)---理解进程操作
文章目录 查看进程通过系统目录查看通过ps命令查看 通过系统调用获取进程标识符通过系统调用创建进程初识fork函数fork函数的返回值 进程状态阻塞与运行状态Linux内核源码中的进程状态运行状态-R浅度睡眠状态-S深度睡眠状态-D暂停状态-T僵尸状态-Z死亡状态-X 查看进程 通过系统…...
基于springcloud实现的医院信息系统
访问【WRITE-BUG数字空间】_[内附完整源码和文档] 医疗信息就诊系统,系统主要功能按照数据流量、流向及处理过程分为临床诊疗、药品管理、财务管理、患者管理。诊疗活动由各工作站配合完成,并将临床信息进行整理、处理、汇总、统计、分析等。本系统包括以…...
设计模式-创建型模式-(工厂、简单工厂、抽象工厂)
一、简单工厂模式 上代码 public class FoodFactory {public static Food makeFood(String name) {if (name.equals("noodle")) {Food noodle new LanZhouNoodle();noodle.addSpicy("more");return noodle;} else if (name.equals("chicken")…...
JAVA12新特性
JAVA12新特性 概述 2019年3月19日,java12正式发布了,总共有8个新的JEP(JDK Enhancement Proposals) JDK 12 is the open-source reference implementation of version 12 of the Java SE12 Platform as specified by by JSR 386 in the Java Community Process. JDK 12 reac…...
Nginx 静态文件、反向代理、负载均衡、缓存、SSL/TLS 加密、gzip 压缩 等等
Nginx的功能 1. 静态文件服务器2. 反向代理服务器3. 负载均衡4. 缓存5. SSL/TLS 加密6. URL 重写7. HTTP/28. WebSocket9. 反向代理缓存10. 安全限制11. gzip 压缩12. 请求限速13. 日志记录14. SSL 证书续订 Nginx 是一个高性能的开源 Web 服务器和反向代理服务器,它…...
Linux设备驱动模型(一)
一、sysfs文件系统 sysfs是一个虚拟文件系统,将内核总的设备对象的链接关系,以文件目录的方式表示出来,并提对设备提供读写接口。 二、kobject kobject是内核中对象表示的基类,可以认为所有的内核对象都是一个kobject kobject单…...
【Python入门篇】——Python基础语法(标识符与运算符)
作者简介: 辭七七,目前大一,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: Python入门,本专栏主要内容为Python的基础语法,Python中的选择循环语句…...
扩展 VirtualBox 已分配磁盘的方法
扩展 VirtualBox 已分配磁盘的方法 第一步:用VirtualBox命令行调整已分配磁盘的大小第二步:用windows磁盘管理工具扩展磁盘空间其他无关配置如何选择虚拟机的芯片组 注意:扩展操作只支持 vdi 格式的磁盘,就是VirtualBox自己的磁盘…...
【LeetCode】646. 最长数对链
646. 最长数对链(中等) 思路 这道题和 300. 最长递增子序列 类似,我们可以定义 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 但是题目中强…...
Makefile教程(Makefile的结构)
文章目录 前言一、Makefile的结构二、深入案例三、Makefile中的一些技巧总结 前言 一、Makefile的结构 Makefile 通常由一系列规则组成,每条规则定义了如何从源文件生成目标文件。每个规则又由目标、依赖和命令三部分组成。 下面是 Makefile 规则的基本结构&…...
SpringMVC(后)SSM整合
10、文件上传和下载 10.1、文件下载 ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文 使用ResponseEntity实现下载文件的功能 RequestMapping("/testDown") public ResponseEntity<byte[]> testResp…...
【博弈论】【第一章】博弈论导论
博弈论导论 【例题】选择数字【例题】巴什博弈【例题】射手博弈博弈论的基本概念:参与人战略行动信息支付函数【例题】分100元 课程概述: 【例题】选择数字 两个参与人A和B,轮流选择[3,4,5,6,7,8,9]中的一个整数(可重复)。当累计…...
keil移植linux(makefile)
文章目录 运行环境:1.1 freeRTOS_LED工程移植1)修改cubeMX配置2)setting设置3)launch设置4)修改makefile5)修改代码6)实验效果 运行环境: ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 robomaster A 板 1.1 freeRTOS_L…...
C++——类和对象(3)
作者:几冬雪来 时间:2023年5月6日 内容:C类和对象内容讲解 目录 前言: 1.运算符重载(续): 2.赋值重载: 结尾: 前言: 在上一篇博客中我们再一次讲解了…...
itop-3568开发板驱动学习笔记(24)设备树(三)时钟实例分析
《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 生产者属性#clock-cells 属性clock-output-namesclock-frequencyassigned-clockclock-indicesassigned-clock-parents 消费者属性 设备树中的时钟信息以时钟树形式体现,时钟树包括时钟的属性和结…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
