消息队列LiteQueue

文章目录

  • 一、简介
  • 二、设计
    • 2.1 队列结构设计
    • 2.2 队列接口设计
  • 三、实现
    • 3.1 队列锁的实现
    • 3.2 创建队列
    • 3.3 写入队列
    • 3.4 读出数据
    • 3.5 判断队列是否为空
    • 3.6 判断队列是否为满
    • 3.7 清空队列
    • 3.8 删除队列
  • 四、测试
  • 参考

一、简介

  • 收到消息时先把接收到的消息放到队列中。
  • 在任务中从队列获取数据。
  • 如果解析过程中再来一帧数据,这帧数据会先存放在消息队列中。
  • 当队列中的上一帧数据解析完成后,任务会从队列中的下一条数据开始解析处理,以此循环,直到队列中的消息解析处理完毕。

二、设计

2.1 队列结构设计

有头尾指针分别指向写入的位置和读出的位置
需要配置队列中最多能存储几帧数据即几个列表项,每一项有多大的空间去保存接收到的数据
在这里插入图片描述
LiteQueue相当于是头部,后面紧跟着的是数据,而且每一个数据的存储大小都是确定的。
考虑到多线程不能同时读或者写,要互斥访问,因此还需要加一个读写锁

/*
LiteQueue : Structure describing queue parameters.
item_num_x: Number of items.
item_size : The size of each list item set when creating the queue,unit: bytes, used to store data received in the queue.
item_size : The counter of items
*/
typedef struct {    volatile uint8_t  queue_write_lock;volatile uint8_t  queue_read_lock;uint8_t   *head;    uint8_t   *tail;size_t    item_num;    size_t    item_size;size_t    item_count; 
}LiteQueue,   *pLiteQueue;

2.2 队列接口设计

使用队列前必定先要创建队列,并确定创建队列的大小,其次是读写队列的接口,以及判断队列是否为空/满、清空队列、删除队列

LiteQueue *LiteQueue_Create(size_t item_num, size_t item_size);  
LiteQueue_Status Write_To_LiteQueue(LiteQueue *queue, uint8_t *buff);  
LiteQueue_Status Read_From_LiteQueue(LiteQueue *queue, uint8_t *buff);
LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue);
LiteQueue_Status LiteQueue_Clear(LiteQueue *queue);
LiteQueue_Status LiteQueue_Delete(LiteQueue *queue);
LiteQueue_Status isLiteQueue_Full(LiteQueue *queue); 
LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue); 

队列的状态用一个枚举类型实现

typedef enum{    LITE_QUEUE_IDLE = 0,    LITE_QUEUE_BUSY,   LITE_QUEUE_ERR,    LITE_QUEUE_OK,LITE_QUEUE_EMPTY,   LITE_QUEUE_NONEMPTY,LITE_QUEUE_FULL,LITE_QUEUE_NONFULL
}LiteQueue_Status;

三、实现

3.1 队列锁的实现

队列锁使用宏定义的方式实现

typedef enum{    LITE_QUEUE_UNLOCK = 0, LITE_QUEUE_LOCK,
}LiteQueueLock;#define  LITE_QUEUE_WRITE_LOCK(__QUEUE__) do{            \if((__QUEUE__)->queue_write_lock == LITE_QUEUE_LOCK){\return LITE_QUEUE_BUSY;                          \} else {                                             \(__QUEUE__)->queue_write_lock = LITE_QUEUE_LOCK; \}                                                    \
}while(0) #define  LITE_QUEUE_WRITE_UNLOCK(__QUEUE__) do{          \(__QUEUE__)->queue_write_lock = LITE_QUEUE_UNLOCK;   \
}while(0)                                                  #define  LITE_QUEUE_READ_LOCK(__QUEUE__) do{             \if((__QUEUE__)->queue_read_lock == LITE_QUEUE_LOCK){ \return LITE_QUEUE_BUSY;                          \} else {                                             \(__QUEUE__)->queue_read_lock = LITE_QUEUE_LOCK;  \}                                                    \
}while(0)       #define  LITE_QUEUE_READ_UNLOCK(__QUEUE__) do{           \(__QUEUE__)->queue_read_lock = LITE_QUEUE_UNLOCK;    \
}while(0)  

3.2 创建队列

/**
* @ brief : Create message queue.
* @ param : {size_t     } item_num : The number of list items in the queue.{size_t     } item_size: The size of each list item, unit: bytes.
* @ return: {LiteQueue *} queue    : Message queue handle pointer.
* @ note  : Create a queue and initialize the queue items to 0, with the head and tail pointers pointing to the starting position of the list items.
*/
LiteQueue *LiteQueue_Create(size_t item_num, size_t item_size){if((item_num < 1) || (item_size < 1)){return NULL;}LiteQueue *queue = (LiteQueue *)malloc(sizeof(LiteQueue) + item_num * item_size);if( queue == NULL ) {printf("LiteQueue malloc failed.\r\n");return NULL;}memset((uint8_t *)queue, 0, sizeof(LiteQueue) + item_num * item_size);queue->head = (uint8_t *)((uint8_t *)queue + sizeof(LiteQueue));queue->tail = queue->head;queue->item_num = item_num;queue->item_size = item_size;queue->item_count = 0;queue->queue_read_lock = LITE_QUEUE_UNLOCK;queue->queue_write_lock = LITE_QUEUE_UNLOCK;return queue;
}

3.3 写入队列

/**
* @ brief : Write data to the queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.{uint8_t        *} buff : Data to be written to the queue.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Writing data when the queue is full will automatically overwrite the first frame of data.
*/
LiteQueue_Status Write_To_LiteQueue(LiteQueue *queue, uint8_t *buff){if((queue == NULL) || (buff == NULL)){return LITE_QUEUE_ERR;}LITE_QUEUE_WRITE_LOCK(queue);if(isLiteQueue_Full(queue) == LITE_QUEUE_FULL){return LITE_QUEUE_FULL;}memcpy(queue->tail, buff, queue->item_size);if(queue->tail == (uint8_t *)queue + sizeof(LiteQueue) + (queue->item_num - 1) * queue->item_size){queue->tail = (uint8_t *)queue + sizeof(LiteQueue);}else{queue->tail += queue->item_size;}queue->item_count += 1;LITE_QUEUE_WRITE_UNLOCK(queue);return LITE_QUEUE_OK;
}

3.4 读出数据

/**
* @ brief : Read data from queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.{uint8_t        *} buff : Data to be read from the queue.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Read data starting from the position of the head pointer and save it to the buff.
*/
LiteQueue_Status Read_From_LiteQueue(LiteQueue *queue, uint8_t *buff){if((queue == NULL) || (buff == NULL) || (isLiteQueue_Empty(queue) == LITE_QUEUE_EMPTY)){return LITE_QUEUE_ERR;}LITE_QUEUE_READ_LOCK(queue);if(isLiteQueue_Empty(queue) == LITE_QUEUE_EMPTY){return LITE_QUEUE_EMPTY;}memcpy(buff, queue->head, queue->item_size);  if(queue->head == (uint8_t *)queue + sizeof(LiteQueue) + (queue->item_num - 1) * queue->item_size){queue->head = (uint8_t *)queue + sizeof(LiteQueue);}else{queue->head += queue->item_size;}queue->item_count -= 1;LITE_QUEUE_READ_UNLOCK(queue);return LITE_QUEUE_OK;  
}

3.5 判断队列是否为空

/**
* @ brief : Determine whether the queue is empty.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,             it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
inline LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue){if(queue == NULL){return LITE_QUEUE_ERR;}if( queue->item_count == 0 ) {return LITE_QUEUE_EMPTY;}else{return LITE_QUEUE_NONEMPTY;} 
}

3.6 判断队列是否为满

/**
* @ brief : Determine whether the queue is full.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,             it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
inline LiteQueue_Status isLiteQueue_Full(LiteQueue *queue){if(queue == NULL){return LITE_QUEUE_ERR;}if( queue->item_count == queue->item_num) {return LITE_QUEUE_FULL;}else{return LITE_QUEUE_NONFULL;} 
}

3.7 清空队列

/**
* @ brief : Clear the message queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
LiteQueue_Status LiteQueue_Clear(LiteQueue *queue){if(queue == NULL) {return LITE_QUEUE_ERR;}LITE_QUEUE_WRITE_LOCK(queue);queue->head = (uint8_t *)((uint8_t *)queue + sizeof(LiteQueue));queue->tail = queue->head;queue->item_count = 0;memset(queue->head, 0, queue->item_num * queue->item_size);LITE_QUEUE_WRITE_UNLOCK(queue);return LITE_QUEUE_OK;
}

3.8 删除队列

/**
* @ brief : Clear the message queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
LiteQueue_Status LiteQueue_Delete(LiteQueue *queue){if(queue == NULL) {return LITE_QUEUE_ERR;}//memset((uint8_t *)queue, 0, sizeof(LiteQueue) + queue->item_num * queue->item_size);free(queue);queue = NULL;return LITE_QUEUE_OK;
}

四、测试

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef unsigned char uint8_t;
typedef unsigned int  uint32_t;/*
LiteQueue : Structure describing queue parameters.
item_num_x: Number of items.
item_size : The size of each list item set when creating the queue,unit: bytes, used to store data received in the queue.
*/
typedef struct {    volatile uint8_t  queue_write_lock;volatile uint8_t  queue_read_lock;uint8_t   *head;    uint8_t   *tail;size_t    item_num;    size_t    item_size;size_t    item_count; 
}LiteQueue,   *pLiteQueue;typedef enum{    LITE_QUEUE_IDLE = 0,    LITE_QUEUE_BUSY,   LITE_QUEUE_ERR,    LITE_QUEUE_OK,LITE_QUEUE_EMPTY,   LITE_QUEUE_NONEMPTY,LITE_QUEUE_FULL,LITE_QUEUE_NONFULL
}LiteQueue_Status;typedef enum{    LITE_QUEUE_UNLOCK = 0, LITE_QUEUE_LOCK,
}LiteQueueLock;#define  LITE_QUEUE_WRITE_LOCK(__QUEUE__) do{            \if((__QUEUE__)->queue_write_lock == LITE_QUEUE_LOCK){\return LITE_QUEUE_BUSY;                          \} else {                                             \(__QUEUE__)->queue_write_lock = LITE_QUEUE_LOCK; \}                                                    \
}while(0) #define  LITE_QUEUE_WRITE_UNLOCK(__QUEUE__) do{          \(__QUEUE__)->queue_write_lock = LITE_QUEUE_UNLOCK;   \
}while(0)                                                  #define  LITE_QUEUE_READ_LOCK(__QUEUE__) do{             \if((__QUEUE__)->queue_read_lock == LITE_QUEUE_LOCK){ \return LITE_QUEUE_BUSY;                          \} else {                                             \(__QUEUE__)->queue_read_lock = LITE_QUEUE_LOCK;  \}                                                    \
}while(0)       #define  LITE_QUEUE_READ_UNLOCK(__QUEUE__) do{           \(__QUEUE__)->queue_read_lock = LITE_QUEUE_UNLOCK;    \
}while(0)   LiteQueue *LiteQueue_Create(size_t item_num, size_t item_size);  
LiteQueue_Status Write_To_LiteQueue(LiteQueue *queue, uint8_t *buff);  
LiteQueue_Status Read_From_LiteQueue(LiteQueue *queue, uint8_t *buff);
LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue);
LiteQueue_Status LiteQueue_Clear(LiteQueue *queue);
LiteQueue_Status LiteQueue_Delete(LiteQueue *queue);
LiteQueue_Status isLiteQueue_Full(LiteQueue *queue); 
LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue); /**
* @ brief : Create message queue.
* @ param : {size_t     } item_num : The number of list items in the queue.{size_t     } item_size: The size of each list item, unit: bytes.
* @ return: {LiteQueue *} queue    : Message queue handle pointer.
* @ note  : Create a queue and initialize the queue items to 0, with the head and tail pointers pointing to the starting position of the list items.
*/
LiteQueue *LiteQueue_Create(size_t item_num, size_t item_size){if((item_num < 1) || (item_size < 1)){return NULL;}LiteQueue *queue = (LiteQueue *)malloc(sizeof(LiteQueue) + item_num * item_size);if( queue == NULL ) {printf("LiteQueue malloc failed.\r\n");return NULL;}memset((uint8_t *)queue, 0, sizeof(LiteQueue) + item_num * item_size);queue->head = (uint8_t *)((uint8_t *)queue + sizeof(LiteQueue));queue->tail = queue->head;queue->item_num = item_num;queue->item_size = item_size;queue->item_count = 0;queue->queue_read_lock = LITE_QUEUE_UNLOCK;queue->queue_write_lock = LITE_QUEUE_UNLOCK;return queue;
}/**
* @ brief : Write data to the queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.{uint8_t        *} buff : Data to be written to the queue.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Writing data when the queue is full will automatically overwrite the first frame of data.
*/
LiteQueue_Status Write_To_LiteQueue(LiteQueue *queue, uint8_t *buff){if((queue == NULL) || (buff == NULL)){return LITE_QUEUE_ERR;}LITE_QUEUE_WRITE_LOCK(queue);if(isLiteQueue_Full(queue) == LITE_QUEUE_FULL){return LITE_QUEUE_FULL;}memcpy(queue->tail, buff, queue->item_size);if(queue->tail == (uint8_t *)queue + sizeof(LiteQueue) + (queue->item_num - 1) * queue->item_size){queue->tail = (uint8_t *)queue + sizeof(LiteQueue);}else{queue->tail += queue->item_size;}queue->item_count += 1;LITE_QUEUE_WRITE_UNLOCK(queue);return LITE_QUEUE_OK;
}/**
* @ brief : Read data from queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.{uint8_t        *} buff : Data to be read from the queue.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Read data starting from the position of the head pointer and save it to the buff.
*/
LiteQueue_Status Read_From_LiteQueue(LiteQueue *queue, uint8_t *buff){if((queue == NULL) || (buff == NULL) || (isLiteQueue_Empty(queue) == LITE_QUEUE_EMPTY)){return LITE_QUEUE_ERR;}LITE_QUEUE_READ_LOCK(queue);if(isLiteQueue_Empty(queue) == LITE_QUEUE_EMPTY){return LITE_QUEUE_EMPTY;}memcpy(buff, queue->head, queue->item_size);  if(queue->head == (uint8_t *)queue + sizeof(LiteQueue) + (queue->item_num - 1) * queue->item_size){queue->head = (uint8_t *)queue + sizeof(LiteQueue);}else{queue->head += queue->item_size;}queue->item_count -= 1;LITE_QUEUE_READ_UNLOCK(queue);return LITE_QUEUE_OK;  
}/**
* @ brief : Determine whether the queue is empty.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,             it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
inline LiteQueue_Status isLiteQueue_Empty(LiteQueue *queue){if(queue == NULL){return LITE_QUEUE_ERR;}if( queue->item_count == 0 ) {return LITE_QUEUE_EMPTY;}else{return LITE_QUEUE_NONEMPTY;} 
}/**
* @ brief : Determine whether the queue is full.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,             it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
inline LiteQueue_Status isLiteQueue_Full(LiteQueue *queue){if(queue == NULL){return LITE_QUEUE_ERR;}if( queue->item_count == queue->item_num) {return LITE_QUEUE_FULL;}else{return LITE_QUEUE_NONFULL;} 
}/**
* @ brief : Clear the message queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
LiteQueue_Status LiteQueue_Clear(LiteQueue *queue){if(queue == NULL) {return LITE_QUEUE_ERR;}LITE_QUEUE_WRITE_LOCK(queue);queue->head = (uint8_t *)((uint8_t *)queue + sizeof(LiteQueue));queue->tail = queue->head;queue->item_count = 0;memset(queue->head, 0, queue->item_num * queue->item_size);LITE_QUEUE_WRITE_UNLOCK(queue);return LITE_QUEUE_OK;
}/**
* @ brief : Clear the message queue.
* @ param : {LiteQueue      *} queue: Message queue handle pointer.
* @ return: {LiteQueue_Status} Returns the status of the queue.
* @ note  : Determine whether the head and tail pointers are the same. If they are the same,it means there is no data in the queue, otherwise it means there is still data that has not been read out.
*/
LiteQueue_Status LiteQueue_Delete(LiteQueue *queue){if(queue == NULL) {return LITE_QUEUE_ERR;}//memset((uint8_t *)queue, 0, sizeof(LiteQueue) + queue->item_num * queue->item_size);free(queue);queue = NULL;return LITE_QUEUE_OK;
}/**
* @ brief : Print the contents of each list item in the queue.
* @ param : {LiteQueue *} queue: Message queue handle pointer.
* @ return: None.
*/
static void PrintLiteQueue(LiteQueue *queue){if(queue == NULL){return ;}for(int i = 0; i < queue->item_num; i++){printf("[item_num:%d] ", i);for(int n = 0; n < queue->item_size; n++){printf("%d ", *((uint8_t *)queue + sizeof(LiteQueue) + i * queue->item_size + n));}printf("\r\n");}
}/**
* @ brief : Print the data in buff.
* @ param : {LiteQueue *} queue: Message queue handle pointer.
* @ return: None.
* @ note  : Used to observe buff data changes and test to verify the correctness of written or read data.
*/
static void PrintBuff(uint8_t *buff, size_t len){if((buff == NULL) || (len < 1)){return ;}printf("Read buff<<<:");for(size_t i = 0; i < len; i++){printf("%d ", buff[i]);}printf("\r\n\r\n");
}int main(){uint8_t writebuff[10] = {0};uint8_t readbuff[10]  = {0};/* Create message queue, 4 list items, each list item has 10 bytes of memory space */pLiteQueue msgQueue = LiteQueue_Create(4, 10);PrintLiteQueue(msgQueue);printf("\r\n");/* Simulate writing and reading to the queue 6 times, and observe the data in the queue by printing */for(int i=0;i<6;i++ ) {/* Simulate data, change the writebuff data and write it to the queue */for(int n = 0; n < msgQueue->item_size; n++){writebuff[n] = (i * msgQueue->item_size + n) % 256;}/* Data is written to the queue */Write_To_LiteQueue(msgQueue, writebuff);PrintLiteQueue(msgQueue);/* Read data from queue */Read_From_LiteQueue(msgQueue, readbuff);PrintBuff(readbuff, sizeof(readbuff));}return 0;
}

在这里插入图片描述

参考

https://mp.weixin.qq.com/s/vI3g4JmSXMyKrpnIV1vjbg

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

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

相关文章

63页!嵩山版Java开发手册分享

作为广受欢迎的编程语言之一&#xff0c;Java在软件开发领域扮演着重要的角色。然而&#xff0c;由于Java的灵活性和广泛应用&#xff0c;很容易出现代码质量低下、可读性差、维护困难等问题。为了解决这些问题&#xff0c;阿里巴巴集团发布了一份权威指南——阿里嵩山版Java开…

【2023年第十三届APMCM亚太地区大学生数学建模竞赛】A题 水果采摘机器人的图像识别 35页论文及python代码

【2023年第十三届APMCM亚太地区大学生数学建模竞赛】A题 水果采摘机器人的图像识别 1 题目 水果采摘机器人的图像识别 中国是世界上最大的苹果生产国&#xff0c;年产量约为3500万吨。与此同时&#xff0c;中国也是世界上最大的苹果出口国&#xff0c;世界上每两个苹果中就有…

iToF人脸识别

iToF(间接飞行时间)是一种测量光飞行时间的技术,主要应用于人脸识别。 iToF人脸识别技术在哪些场景下会用到 iToF人脸识别技术可以应用于许多场景,以下是一些常见的应用场景: 平安城市:在城市监控系统中,iToF人脸识别技术可以用于实时监控、目标检测和识别,以及异常行为…

WEB 3D技术 three.js通过光线投射 完成几何体与外界的事件交互

本文 我们来说 光线投射 光线投射技术是用于3维空间场景中的交互事件 我们先编写代码如下 import ./style.css import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";const scene new THRE…

添加 Android App Links

添加 Android App Links功能 介绍一个简单的效果Android配置Add Url intent filtersAdd logic to handle the intentAssociate website 搭建网页支持AppLinks 介绍 Android App Links 是指将用户直接转到 Android 应用内特定内容的 HTTP 网址。Android App Links 可为您的应用带…

机械过滤器(石英砂过滤器)和多介质过滤器的区别 工作原理动画

​ 1&#xff1a;机械过滤器多介质石英砂过滤器介绍 机械过滤器&#xff1a;预处理水质的关键设备 机械过滤器&#xff0c;也被称为压力式过滤器&#xff0c;是纯水制备过程中不可或缺的预处理设备。它在水处理系统中扮演着重要的角色&#xff0c;能够有效地去除水中的悬浮物…

《Python机器学习原理与算法实现》学习笔记

以下为《Python机器学习原理与算法实现》&#xff08;杨维忠 张甜 著 2023年2月新书 清华大学出版社&#xff09;的学习笔记。 根据输入数据是否具有“响应变量”信息&#xff0c;机器学习被分为“监督式学习”和“非监督式学习”。 “监督式学习”即输入数据中即有X变量&…

Linux服务器搭建笔记-006:拓展/home目录容量

一、问题说明 Ubuntu服务器在使用过程中创建的新用户&#xff0c;每位用户会在/home目录下生成一个属于其个人的主文件夹。如果不限制各个用户的使用空间&#xff0c;所有的用户都会共用/home所挂载的硬盘。在这种多用户情况下&#xff0c;会很快的填满/home目录&#xff0c;导…

uniapp 添加自定义图标

1. 下载自定义图标 在阿里图标库&#xff0c;选择喜欢的图标库 https://www.iconfont.cn/collections/index 建议按收藏数排序进行&#xff0c;能更快找到合适的图标 点开喜欢的图标库&#xff08;如 Ant Design 官方图标库&#xff09;&#xff0c;将喜欢的图标添加到图标收集…

仿网易云音乐网站PHP源码,可运营的原创音乐分享平台源码,在线音乐库系统

源码介绍 使用PHP和MYSQL开发的原创音乐分享平台源码&#xff0c;仿网易云音乐网站。用户可以在网站上注册并上传自己的音乐作品&#xff0c;系统内置广告系统&#xff0c;为网站创造收入来源。 安装教程 1.导入sql.sql 2.修改 includes\config.php 数据库信息和网址都改成…

B2005 字符三角形(python)

a input() print( a) print( a a a) print(a a a a a)python中默认输入的是字符型&#xff0c;第一句就是输入了一个字符赋给a python中单引号内的也是字符串&#xff0c;用print输出需要连接的字符串时用加号加在后面即可

数据结构:基于数组的环形队列(循环队列)实现

1 前言 队列是一种先进先出的线性表&#xff0c;简称为FIFO。它只允许在队尾插入成员&#xff0c;在队头删除成员&#xff0c;就像现实生活中排队上车一样。 队列的实现可以通过链表或数组完成&#xff0c;一般来说都推荐使用链表来实现队列&#xff0c;使用数组实现队列时每次…

Casper Network 推出 “DevRewards” 计划:允许所有开发者赚取激励

Casper Association 是一个致力于推动区块链大规模采用的非营利组织&#xff0c;该组织在 Casper Network 系统中推出了一个被称为 “DevRewards ” 的奖励计划&#xff0c;旨在邀请开发者提交能够解决现有问题的创新技术方案&#xff0c;以帮助 Casper Network 系统进一步完善…

idea部署javaSE项目(awt+swing项目)_idea导入eclipse的javaSE项目

一.idea打开项目 选择需要部署的项目 二、设置JDK 三、引入数据库驱动包 四、执行sql脚本 四、修改项目的数据库连接 找到数据库连接文件 五.其他系统实现 JavaSwing实现学生选课管理系统 JavaSwing实现学校教务管理系统 JavaSwingsqlserver学生成绩管理系统 JavaSwing用…

c语言:用指针输入两个数组|练习题

一、题目 利用指针&#xff0c;输入两个数组 如图&#xff1a; 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> int main() { int a[50]; int b[50]; int *paa,*pbb; //输入第一组数组 printf("请输入第一组5个数字&#xff1a;…

计算机网络课程设计-企业网三层架构

&#xff08;单人版&#xff09; 摘 要 本篇报告主要解决了为一家名为西宫的公司网络搭建问题&#xff0c;该网络采用企业网三层架构对完了过进行设计。首先使用以太网中继&#xff0c;主要使用VLAN划分的技术来划定不同部门。使用MSTP对每个组配置生成树&#xff0c;防止交换机…

fastApi 项目部署

方式一&#xff0c;Uvicorn部署 Run a Server Manually - Uvicorn - FastAPI 1&#xff0c;linux服务器安装 python>3.8 2&#xff0c;安装 uvicorn : pip install "uvicorn[standard]" 3&#xff0c;上传项目到服务器 main.py from typing imp…

Leetcode每日一题周汇总 (12.24-12.30)

Leetcode每日一题周汇总 (12.24-12.30) 1.Sunday (12.24) 题目链接&#xff1a;1954. 收集足够苹果的最小花园周长 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标…

设计模式设计原则——依赖倒置原则(DIP)

DIP&#xff1a;Dependence Inversion Principle 原始定义&#xff1a;High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions。 官…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型&#xff0c;用于创造和修改图像。这个模型能够基于文本描述来生成图像&#xff0c;让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API&#xff0c;通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…