原子学习笔记4——GPIO 应用编程
一、应用层如何操控 GPIO
与 LED 设备一样,GPIO 同样也是通过 sysfs 方式进行操控,进入到/sys/class/gpio 目录下,如下所示:
-
gpiochipX:当前 SoC 所包含的 GPIO 控制器,我们知道 I.MX6UL/I.MX6ULL 一共包含了 5 个 GPIO控制器,分别为 GPIO1、GPIO2、GPIO3、GPIO4、GPIO5,在这里分别对应 gpiochip0、gpiochip32、gpiochip64、gpiochip96、gpiochip128 这 5 个文件夹,每一个 gpiochipX 文件夹用来管理一组 GPIO。随便进入到其中某个目录下,可以看到这些目录下包含了如下文件:
在这个目录我们主要关注的是 base、label、ngpio 这三个属性文件,这三个属性文件均是只读、不可写。 -
base:与 gpiochipX 中的 X 相同,表示该控制器所管理的这组 GPIO 引脚中最小的编号。每一个 GPIO引脚都会有一个对应的编号,Linux 下通过这个编号来操控对应的 GPIO 引脚。
可以看出gpiochip0最小编号为0,而gpiochip32最小编号为32. -
label:该组 GPIO 对应的标签,也就是名字。
-
ngpio:该控制器所管理的 GPIO 引脚的数量(所以引脚编号范围是:base ~ base+ngpio-1)。
对于给定的一个 GPIO 引脚,如何计算它在 sysfs 中对应的编号呢?其实非常简单,譬如给定一个 GPIO引脚为 GPIO4_IO16,那它对应的编号是多少呢?首先我们要确定 GPIO4 对应于gpiochip96,该组 GPIO 引脚的最小编号是 96(对应于 GPIO4_IO0),所以 GPIO4_IO16 对应的编号自然是 96 + 16 = 112;同理GPIO3_IO20 对应的编号是 64 + 20 = 84。 -
export:用于将指定编号的 GPIO 引脚导出。在使用 GPIO 引脚之前,需要将其导出,导出成功之后才能使用它。注意 export 文件是只写文件,不能读取,将一个指定的编号写入到 export 文件中即可将对应的 GPIO 引脚导出,譬如:
echo 0 > export # 导出编号为 0 的 GPIO 引脚(对于 I.MX6UL/I.MX6ULL 来说,也就是GPIO1_IO0)
导出成功之后会发现在/sys/class/gpio 目录下生成了一个名为 gpio0 的文件夹(gpioX,X 表示对应的编号),如图所示。这个文件夹就是导出来的 GPIO 引脚对应的文件夹,用于管理、控制该 GPIO 引脚。
- unexport:将导出的 GPIO 引脚删除。当使用完 GPIO 引脚之后,我们需要将导出的引脚删除,同样该文件也是只写文件、不可读,譬如:
echo 0 > unexport # 删除导出的编号为 0 的 GPIO 引脚
删除成功之后,之前生成的 gpio0 文件夹就会消失!
控制 GPIO 引脚主要是通过 export 导出之后所生成的 gpioX(X 表示对应的编号)文件夹,在该文件夹目录下存在一些属性文件可用于控制 GPIO引脚的输入、输出以及输出的电平状态等。
Tips:需要注意的是,并不是所有 GPIO 引脚都可以成功导出,如果对应的 GPIO 已经在内核中被使用了,那便无法成功导出,打印如下信息:
那也就是意味着该引脚已经被内核使用了,譬如某个驱动使用了该引脚,那么将无法导出成功!
gpioX
将指定的编号写入到 export 文件中,可以导出指定编号的 GPIO 引脚,导出成功之后会在/sys/class/gpio目录下生成对应的 gpioX(X 表示 GPIO 的编号)文件夹,以前面所生成的 gpio0 为例,进入到 gpio0 目录,该目录下的文件如下所示:
我们主要关心的文件是 active_low、direction、edge 以及 value 这四个属性文件,接下来分别介绍这四个属性文件的作用:
- direction:配置 GPIO 引脚为输入或输出模式。该文件可读、可写,读表示查看 GPIO 当前是输入还是输出模式,写表示将 GPIO 配置为输入或输出模式;读取或写入操作可取的值为"out"(输出模式)和"in"(输入模式),如下所示:
- value:在 GPIO 配置为输出模式下,向 value 文件写入"0"控制 GPIO 引脚输出低电平,写入"1"则控制 GPIO 引脚输出高电平。在输入模式下,读取 value 文件获取 GPIO 引脚当前的输入电平状态。譬如:
# 获取 GPIO 引脚的输入电平状态
echo "in" > direction
cat value
# 控制 GPIO 引脚输出高电平
echo "out" > direction
echo "1" > value
- active_low:这个属性文件用于控制极性,可读可写,默认情况下为 0,譬如:
# active_low 等于 0 时
echo "0" > active_low
echo "out" > direction
echo "1" > value #输出高
echo "0" > value #输出低
# active_low 等于 1 时
$ echo "1" > active_low
$ echo "out" > direction
$ echo "1" > value #输出低
$ echo "0" > value #输出高
由此看出,active_low 的作用已经非常明显了,对于输入模式来说也同样适用。
- edge:控制中断的触发模式,该文件可读可写。在配置 GPIO 引脚的中断触发模式之前,需将其设置为输入模式:
非中断引脚:echo "none" > edge
上升沿触发:echo "rising" > edge
下降沿触发:echo "falling" > edge
边沿触发:echo "both" > edge
当引脚被配置为中断后可以使用 poll()函数监听引脚的电平状态变化。
二、GPIO 应用编程之输出
上一小节已经向大家介绍了如何通过 sysfs 方式控制开发板上的 GPIO 引脚,本小节我们编写一个简单地测试程序,控制开发板上的某一个 GPIO 输出高、低不同的电平状态,其示例代码如下所示:
// 示例代码 16.2.1 控制 GPIO 输出高低电平
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
static char gpio_path[100];
static int gpio_config(const char *attr, const char *val)
{char file_path[100];int len;int fd;sprintf(file_path, "%s/%s", gpio_path, attr);if (0 > (fd = open(file_path, O_WRONLY))) {perror("open error");return fd;}len = strlen(val);if (len != write(fd, val, len)) {perror("write error");close(fd);return -1;}close(fd); //关闭文件return 0;
}
int main(int argc, char *argv[])
{// /* 校验传参 if (3 != argc) {fprintf(stderr, "usage: %s <gpio> <value>\n", argv[0]);exit(-1);}// /* 判断指定编号的 GPIO 是否导出 sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]);if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出int fd;int len;if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {perror("open error");exit(-1);}len = strlen(argv[1]);if (len != write(fd, argv[1], len)) {//导出 gpioperror("write error");close(fd);exit(-1);}close(fd); //关闭文件}// /* 配置为输出模式 if (gpio_config("direction", "out"))exit(-1);// /* 极性设置 if (gpio_config("active_low", "0"))exit(-1);// /* 控制 GPIO 输出高低电平 if (gpio_config("value", argv[2]))exit(-1);// /* 退出程序 exit(0);
}
执行程序时需要传入两个参数,argv[1]指定 GPIO 的编号、argv[2]指定输出电平状态(0 表示低电平、1 表示高电平)。
上述代码中首先使用 access()函数判断指定编号的 GPIO 引脚是否已经导出,也就是判断相应的 gpioX目录是否存在,如果不存在则表示未导出,则通过"/sys/class/gpio/export"文件将其导出;导出之后先配置了GPIO 引脚为输出模式,也就是向 direction 文件中写入"out";接着再配置极性,通过向 active_low 文件中写入"0"(不用配置也可以);最后再控制 GPIO 引脚输出相应的电平状态,通过对 value 属性文件写入"1"或"0"来使其输出高电平或低电平。
测试:编译的到的可执行文件拷贝到开发板 Linux 系统用户家目录下,执行该应用程序控制开发板上的 GPIO1_IO01 引脚输出高或低电平:
./gpio_out 1 1 #控制 GPIO1_IO01 输出高电平
./gpio_out 1 0 #控制 GPIO1_IO01 输出低电平
执行相应的命令后,可以使用万用表或者连接一个 LED 小灯进行检验,以验证实验结果!
三、GPIO 应用编程之输入
编写一个读取 GPIO 电平状态的测试程序
// 示例代码 16.3.1 读取 GPIO 电平状态
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
static char gpio_path[100];
static int gpio_config(const char *attr, const char *val)
{char file_path[100];int len;int fd;sprintf(file_path, "%s/%s", gpio_path, attr);if (0 > (fd = open(file_path, O_WRONLY))) {perror("open error");return fd;}len = strlen(val);if (len != write(fd, val, len)) {perror("write error");close(fd);return -1;}close(fd); //关闭文件return 0;
}
int main(int argc, char *argv[])
{char file_path[100];char val;int fd;// /* 校验传参 if (2 != argc) {fprintf(stderr, "usage: %s <gpio>\n", argv[0]);exit(-1);}// /* 判断指定编号的 GPIO 是否导出 sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]);if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出int len;if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {perror("open error");exit(-1);}len = strlen(argv[1]);if (len != write(fd, argv[1], len)) {//导出 gpioperror("write error");close(fd);exit(-1);}close(fd); //关闭文件}// /* 配置为输入模式 if (gpio_config("direction", "in"))exit(-1);// /* 极性设置 if (gpio_config("active_low", "0"))exit(-1);// /* 配置为非中断方式 if (gpio_config("edge", "none"))exit(-1);// /* 读取 GPIO 电平状态 sprintf(file_path, "%s/%s", gpio_path, "value");if (0 > (fd = open(file_path, O_RDONLY))) {perror("open error");exit(-1);}if (0 > read(fd, &val, 1)) {perror("read error");close(fd);exit(-1);}printf("value: %c\n", val);// /* 退出程序 close(fd);exit(0);
}
执行程序时需要传入一个参数,argv[1]指定要读取电平状态的 GPIO 对应的编号。
上述代码中首先使用 access()函数判断指定编号的 GPIO 引脚是否已经导出,若未导出,则通过
“/sys/class/gpio/export"文件将其导出;导出之后先配置了 GPIO 引脚为输入模式,也就是向 direction 文件中写入"in”;接着再配置极性、设置 GPIO 引脚为非中断模式(向 edge 属性文件中写入"none")。最后打开 value 属性文件,读取 GPIO 的电平状态并将其打印出来。
测试:编译的到的可执行文件拷贝到开发板 Linux 系统用户家目录下,执行该应用程序以读取 GPIO1_IO01 引脚此时的电平状态,是高电平还是低电平?
首先通过杜邦线将 GPIO1_IO01 引脚连接到板子上的 3.3V 电源引脚上,接着执行命令读取 GPIO 电平状态:
打印出的 value 等于 1,表示读取到 GPIO 的电平确实是高电平;接着将 GPIO1_IO01 引脚连接到板子上的 GND 引脚上,执行命令:
打印出的 value 等于 0,表示读取到 GPIO 的电平确实是低电平;测试结果与实际相符合!
四、GPIO 应用编程之中断
在应用层可以将 GPIO 配置为中断触发模式,譬如将 GPIO 配置为上升沿触发、下降沿触发或者边沿触发,本小节我们来编写一个测试程序,将 GPIO 配置为边沿触发模式并监测中断触发状态。其示例代码如下所示:
// 示例代码 16.4.1 监测 GPIO 中断触发
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
static char gpio_path[100];
static int gpio_config(const char *attr, const char *val)
{char file_path[100];int len;int fd;sprintf(file_path, "%s/%s", gpio_path, attr);if (0 > (fd = open(file_path, O_WRONLY))) {perror("open error");return fd;}len = strlen(val);if (len != write(fd, val, len)) {perror("write error");return -1;}close(fd); //关闭文件return 0;
}
int main(int argc, char *argv[])
{struct pollfd pfd;char file_path[100];int ret;char val;/* 校验传参 */if (2 != argc) {fprintf(stderr, "usage: %s <gpio>\n", argv[0]);exit(-1);}/* 判断指定编号的 GPIO 是否导出 */sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]);if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出int len;int fd;if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {perror("open error");exit(-1);}len = strlen(argv[1]);if (len != write(fd, argv[1], len)) {//导出 gpioperror("write error");exit(-1);}close(fd); //关闭文件}/* 配置为输入模式 */if (gpio_config("direction", "in"))exit(-1);/* 极性设置 */if (gpio_config("active_low", "0"))exit(-1);/* 配置中断触发方式: 上升沿和下降沿 */if (gpio_config("edge", "both"))exit(-1);/* 打开 value 属性文件 */sprintf(file_path, "%s/%s", gpio_path, "value");if (0 > (pfd.fd = open(file_path, O_RDONLY))) {perror("open error");exit(-1);}/* 调用 poll */pfd.events = POLLPRI; //只关心高优先级数据可读(中断)read(pfd.fd, &val, 1);//先读取一次清除状态for ( ; ; ) {ret = poll(&pfd, 1, -1); //调用 pollif (0 > ret) {perror("poll error");exit(-1);}else if (0 == ret) {fprintf(stderr, "poll timeout.\n");continue;}/* 校验高优先级数据是否可读 */if(pfd.revents & POLLPRI) {if (0 > lseek(pfd.fd, 0, SEEK_SET)) {//将读位置移动到头部perror("lseek error");exit(-1);}if (0 > read(pfd.fd, &val, 1)) {perror("read error");exit(-1);}printf("GPIO 中断触发<value=%c>\n", val);}}/* 退出程序 */exit(0);
}
执行程序时需要传入一个参数,argv[1]指定要读取电平状态的 GPIO 对应的编号。
上述代码中首先使用 access()函数判断指定编号的 GPIO 引脚是否已经导出,若未导出,则通过
"/sys/class/gpio/export"文件将其导出。对 GPIO 进行配置:配置为输入模式、配置极性、将触发方式配置为边沿触发。
打开 value 属性文件,获取到文件描述符,接着使用 poll()函数对 value 的文件描述符进行监视,这里为什么要使用 poll()监视、而不是直接对文件描述符进行读取操作?这里简单的描述一下。poll()函数可以监视一个或多个文件描述符上的 I/O 状态变化,譬如 POLLIN、POLLOUT、POLLERR、POLLPRI 等,其中 POLLIN 和 POLLOUT 表示普通优先级数据可读、可写,而 POLLPRI 表示有高优先级数据可读取,中断就是一种高优先级事件,当中断触发时表示有高优先级数据可被读取。
测试:编译的到的可执行文件拷贝到开发板 Linux 系统用户家目录下,执行该应用程序可
以监测 GPIO 的中断触发。执行应用程序监测 GPIO1_IO01 引脚的中断触发情况,如下所示:
当执行命令之后,我们可以使用杜邦线将 GPIO1_IO01 引脚连接到 GND 或 3.3V 电源引脚上,来回切换,使得 GPIO1_IO01 引脚的电平状态发生由高到低或由低到高的状态变化,以验证 GPIO 中断的边沿触发情况;当发生中断时,终端将会打印相应的信息,如上图所示。
相关文章:

原子学习笔记4——GPIO 应用编程
一、应用层如何操控 GPIO 与 LED 设备一样,GPIO 同样也是通过 sysfs 方式进行操控,进入到/sys/class/gpio 目录下,如下所示: gpiochipX:当前 SoC 所包含的 GPIO 控制器,我们知道 I.MX6UL/I.MX6ULL 一共包…...
查看iqn编码
cat /etc/iscsi/initiatorname.iscsi ## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames. InitiatorNameiqn.2004-10.com.ubuntu:01:9ebe1a68...

如何安全的使用密码登录账号(在不知道密码的情况下)
首先,需要用到的这个工具: 度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 1、打开工具,进入账号密码模块,如图 2、看到鼠标移动到密码那一栏有提示,按住Ctrl或者Alt点击或者双击就能复制内容&…...
软件需求和设计评审
目录 引言 1. 软件评审的方法和技术 2. 产品需求评审:构建正确的产品 3. 设计评审:构建正确的产品 4. 软件评审的最佳实践 结语 引言 在软件开发的迷宫中,需求和设计评审是通往成功产品的关键门户。它们是确保软件质量和满足用户需求的…...

论文笔记ColdDTA:利用数据增强和基于注意力的特征融合进行药物靶标结合亲和力预测
ColdDTA发表在Computers in Biology and Medicine 的一篇一区文章 突出 • 数据增强和基于注意力的特征融合用于药物靶点结合亲和力预测。 • 与其他方法相比,它在 Davis、KIBA 和 BindingDB 数据集上显示出竞争性能。 • 可视化模型权重可以获得可解释的见解。 …...

如何防止WordPress网站内容被抓取
最近在检查网站服务器的访问日志的时候,发现了大量来自同一个IP地址的的请求,用站长工具分析确认了我的网站内容确实是被他人的网站抓取了,我第一时间联系了对方网站的服务器提供商投诉了该网站,要求对方停止侵权行为,…...
全球化战略中的技术支柱:出海企业的网络技术解决方案
随着全球市场的一体化,中国的电商与游戏行业越来越倾向于扩展国际市场,这一过程被称为“出海”。成功的出海战略不仅需要强大的市场洞察和文化适应能力,还需依赖高效的网络技术,包括SOCKS5代理、代理IP、以及全面的网络安全策略。…...

在Linux上安装并运行RabbitMQ
目录 准备CentOS服务器 下载rabbit-server和erlang文件 启动RabbitMQ服务 准备CentOS服务器 两个命令,选一个能用的,查看CentOS服务器的版本 lsb_release -a下载rabbit-server和erlang文件 参考文章:http://t.csdnimg.cn/t8BbM 1、创建新…...

使用 docker-compose 搭建个人博客 Halo
说明 我这里使用的是 Halo 作为博客的工具,毕竟是开源了,也是使用 Java 写的嘛,另外一点就是使用 docker 来安装(自动挡,不用自己考虑太多的环境因素),这样子搭建起来更快一点,我们…...

《这就是ChatGPT》读书笔记
书名:这就是ChatGPT 作者:[美] 斯蒂芬沃尔弗拉姆(Stephen Wolfram) ChatGPT在做什么? ChatGPT可以生成类似于人类书写的文本,它基本任务是弄清楚如何针对它得到的任何文本产生“合理的延续”。当ChatGPT写…...

更专业的汽车软件研发工具链,怿星重磅发布新产品
怿星科技在2024北京国际车展同期举办主题为“创新引领未来——聚焦智能汽车软件新基建”的新产品发布会,重磅推出1款绝对优势产品和4套场景解决方案。同时举行了4场热点技术研讨:国产工具链的机遇与挑战、新架构下的的车载DDS应用探索及测试方案介绍、软…...

Stable Diffusion:AI绘画的新纪元
摘要: Stable Diffusion(SD)作为AI绘画领域的新星,以其开源免费、强大的生成能力和高度的自定义性,正在引领一场艺术与技术的革命。本文旨在为读者提供Stable Diffusion的全面介绍,包括其原理、核心组件、安…...
有5个excel表,每个表有6列。用python把这5个表合成1个表。
要将五个Excel表格合并成一个表格,我们可以使用pandas库,它提供了一个简单且强大的方式来处理和分析数据。下面是一个步骤说明和示例代码: 步骤: 安装pandas和openpyxl(如果你还没有安装的话):…...

【回溯算法】【Python实现】最大团问题
文章目录 [toc]问题描述回溯算法Python实现时间复杂性 问题描述 给定无向图 G ( V , E ) G (V , E) G(V,E),如果 U ⊆ V U \subseteq V U⊆V,且对任意 u u u, v ∈ U v \in U v∈U有 ( u , v ) ∈ E (u , v) \in E (u,v)∈E,则称…...

CMakeLists.txt语法规则:foreach 循环基本用法
一. 简介 cmake 中除了 if 条件判断之外,还支持循环语句,包括 foreach()循环、while()循环。 本文学习 CMakeLists.txt语法中的循环语句。 CMakeLists.txt语法中 有两种 循环实现方式:foreach循环与 while循环。 二. CMakeLists.txt语法规则…...

redis集群-主从机连接过程
首先从机需要发送自身携带的replid和offset向主机请求连接 replid:replid是所有主机在启动时会生成的一个固定标识,它表示当前复制流的id,当从机第一次请求连接时,主机会将自己的replid发送给从机,从机在接下来的请求…...

去哪里找高清视频素材?推荐几个短视频素材免费网站
在数字时代,视频内容的质量直接影响观众的吸引力和留存率。尤其是高清、4K视频素材和可商用素材,它们在提升视觉质量和叙事深度方面起到了至关重要的作用。以下是一些国内外的顶级视频素材网站,它们提供的资源将为您的创作提供极大的支持和灵…...

从互联网医院源码到搭建:开发视频问诊小程序的技术解析
如今,视频问诊小程序作为医疗服务的一种新形式,正逐渐受到人们的关注和青睐。今天,小编将为您详解视频问诊小程序的开发流程。 一、背景介绍 互联网医院源码是视频问诊小程序开发的基础,它提供了一套完整的医疗服务系统框架&…...

【Linux】常见指令(二)
mv指令 mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files) 是Linux系统下常用的命令,经常用来备份文件或者目录 功能: 1.剪切文件或者目录 2.对文件或者目录进行重命名 常用选项: -f …...
python元类与C#、Java中的反射
Python的元类和C#中的反射 在概念上有一定的相似性,但它们的目的和使用方式有所不同。 Python的元类: 元类(Metaclass)是控制类创建的类。它们定义了类的创建过程,可以修改类的行为。元类通过定制类的创建过程&…...

深度学习|pytorch基本运算-hadamard积、点积和矩阵乘法
【1】引言 pytorch对张量的基本运算和线性代数课堂的教学有一些区别,至少存在hadamard积、点积和矩阵乘法三种截然不同的计算方法。 【2】hadamard积 hadamard积是元素对位相乘,用“*”连接张量,代码: # 导入包 import torch …...

可视化大屏通用模板Axure原型设计案例
本文将介绍一款基于Axure设计的可视化大屏通用模板,适用于城市、网络安全、园区、交通、社区、工业、医疗、能源等多个领域。 模板概述 这款Axure可视化大屏通用模板集成了多种数据展示模块和组件,旨在为用户提供一个灵活、可定制的数据展示平台。无论…...

UE5 2D地图曝光太亮怎么修改
UE5 2D地图曝光怎么修改 在场景添加后期处理体积 修改后期处理体积Exposure曝光参数最大值最小值都改为0 勾选Infinite Extend 全地图范围应用此后期处理体积...

【多线程初阶】内存可见性问题 volatile
文章目录 再谈线程安全问题内存可见性问题可见性问题案例编译器优化 volatileJava内存模型(JMM) 再谈线程安全问题 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该有的结果,则说这个程序是线程安全的,反之,多线程环境中,并发执行后,产生bug就是线程不安全…...
OIer常用的软件
前言 现在许多软件的官网多不好找,所以我今天就将常用的一些软件官网地址翻了出来,并简单介绍了他的用法。 正文 1.DEV-C DEV-C 用途:c编译软件,是OIer的生涯之路的必备软件 2.Katex KATex 用途:展现公式的软件&…...

【C语言极简自学笔记】项目开发——扫雷游戏
一、项目概述 1.项目背景 扫雷是一款经典的益智游戏,由于它简单而富有挑战性的玩法深受人们喜爱。在 C 语言学习过程中,开发扫雷游戏是一个非常合适的实践项目,它能够综合运用 C 语言的多种基础知识,如数组、函数、循环、条件判…...
第十一篇:MySQL 在分布式系统中的一致性保障与中间件实践
随着微服务和分布式架构的发展,单点数据库早已无法满足系统的横向扩展需求。本篇聚焦 MySQL 在分布式系统中的一致性保障机制,以及相关中间件的使用策略与实战经验。 一、一致性问题的由来 在 单机 MySQL 环境 中,事务具有原子性、隔离性&am…...
初识 Pytest:测试世界的智能助手
概述 在编写程序的过程中,我们常常需要确认代码是否按照预期工作。为了提高效率并减少人为错误,我们可以借助工具来帮助我们完成这一过程。Pytest 就是这样一个用于编写和运行测试的 Python 工具。 什么是 Pytest? Pytest 是一个用于 Pyth…...

设计模式——模版方法设计模式(行为型)
摘要 模版方法设计模式是一种行为型设计模式,定义了算法的步骤顺序和整体结构,将某些步骤的具体实现延迟到子类中。它通过抽象类定义模板方法,子类实现抽象步骤,实现代码复用和算法流程控制。该模式适用于有固定流程但部分步骤可…...
盲盒经济2.0:数字藏品开箱是否适用赌博法规
首席数据官高鹏律师团队编著 一、年轻人的“盲盒信仰”,法律的灰色地带 近年来,“盲盒经济”从实体玩具扩展到数字藏品领域,掀起了一波全民开箱热潮。年轻人在社交平台上晒出“开箱暴击”的喜悦,平台方则以“限量发行”“价值赋…...