当前位置: 首页 > news >正文

gcc编译

一、GCC简介

GCC(GNU Compiler Collection)是 GNU 工具链的主要组成部分,是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件,由 Richard Stallman 于 1985 年开始开发。
GCC 原名为 GNU C语言编译器,因为它原本只能处理 C 语言,但如今的 GCC 不仅可以编译 C、C++ 和 Objective-C,还可以通过不同的前端模块支持各种语言,包括 Java、Fortran、Ada、Pascal、Go 和 D 语言等等。
GCC 的编译过程可以划分为四个阶段
  • 预处理(Pre-Processing):生成 .i 的文件[预处理器cpp]
  • 编译(Compiling):  将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]
  • 汇编(Assembling):  由汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]
  • 链接生成可执行文件(Linking) [链接器ld]

 

安装:
# 安装c编译器(linux需安装python-devel, gcc)
centos: yum install python-devel  gcc
ubuntu: apt-get install build-essential

二、GCC使用

nist@zq-node2:~/test$ gcc --help
Usage: gcc [options] file...
Options:-pass-exit-codes         从一个阶段以最高错误代码退出.--help                   Display this information.--target-help            显示特定于目标的命令行选项.--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].显示特定类型的命令行选项.(使用 '-v --help' 显示子进程的命令行选项).--version                显示编译器版本信息.-dumpspecs               显示所有内置规范字符串.-dumpversion             显示编译器的版本.-dumpmachine             显示编译器的目标处理器.-print-search-dirs       显示编译器搜索路径中的目录.-print-libgcc-file-name  显示编译器配套库的名称.-print-file-name=<lib>   显示库 <lib> 的完整路径.-print-prog-name=<prog>  显示编译器组件 <prog> 的完整路径.-print-multiarch         显示目标的规范化 GNU 三元组,用作库路径中的一个组件.-print-multi-directory   显示 libgcc 版本的根目录.-print-multi-lib         显示命令行选项和多个库搜索目录之间的映射.-print-multi-os-directory 显示操作系统库的相对路径.-print-sysroot           显示目标库目录.-print-sysroot-headers-suffix 显示用于查找headers的sysroot后缀.-Wa,<options>            将逗号分隔的 <options> 传递给汇编器(assembler).-Wp,<options>            将逗号分隔的 <options> 传递给预处理器(preprocessor)-Wl,<options>            将逗号分隔的 <options> 传递给链接器(linker)-Xassembler <arg>        将 <arg> 传递给汇编器(assembler).-Xpreprocessor <arg>     将 <arg> 传递给预处理器(preprocessor).-Xlinker <arg>           将 <arg> 传递给链接器(linker).-save-temps              不用删除中间文件.-save-temps=<arg>        不用删除指定的中间文件.-no-canonical-prefixes   在构建其他 gcc 组件的相对前缀时,不要规范化路径.-pipe                    使用管道而不是中间文件-time                    为每个子流程的执行计时.-specs=<file>            使用 <file> 的内容覆盖内置规范.-std=<standard>          假设输入源用于<standard>。--sysroot=<directory>    使用<standard>作为headers和libraries的根目录.-B <directory>           将 <directory> 添加到编译器的搜索路径.-v                       显示编译器调用的程序.-###                     与 -v 类似,但引用的选项和命令不执行.-E                       仅执行预处理(不要编译、汇编或链接).-S                       只编译(不汇编或链接).-c                       编译和汇编,但不链接.-o <file>                指定输出文件. gcc 编译出来的文件默认是 a.out-pie                     创建一个动态链接、位置无关的可执行文件-shared                  创建共享库/动态库.-g:                     生成调试信息-w:                       不生成任何警告-Wall:                    编译时 显示Warning警告,但只会显示编译器认为会出现错误的警告-x <language>         指定以下输入文件的语言。允许的语言包括:c c++汇编程序none“none”表示恢复到的默认行为根据文件的扩展名猜测语言。
Options starting with -g, -f, -m, -O, -W, or --param are automaticallypassed on to the various sub-processes invoked by gcc.  In order to passother options on to these processes the -W<letter> options must be used.
For bug reporting instructions, please see:
<file:///usr/share/doc/gcc-9/README.Bugs>.-shared:
编译动态库时要用到
-pthread:
在Linux中要用到多线程时,需要链接pthread库
-fPIC:
作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),
则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意
位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
-fwrapv:
它定义了溢出时候编译器的行为——采用二补码的方式进行操作
-O参数
这是一个程序优化参数,一般用-O2就是,用来优化程序用的
-O2:
会尝试更多的寄存器级的优化以及指令级的优化,它会在编译期间占用更多的内存和编译时间。
-O3: 在O2的基础上进行更多的优化
-Wall:
编译时 显示Warning警告,但只会显示编译器认为会出现错误的警告
-fno-strict-aliasing:
“-fstrict-aliasing”表示启用严格别名规则,“-fno-strict-aliasing”表示禁用严格别名规则,当gcc的编译优化参数为“-O2”、“-O3”和“-Os”时,默认会打开“-fstrict-aliasing”。
-I (大写的i):
是用来指定头文件目录
-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-l:
-l(小写的 L)参数就是用来指定程序要链接的库,-l参数紧接着就是库名,把库文件名的头lib和尾.so去掉就是库名了,例如我们要用libtest.so库库,编译时加上-ltest参数就能用上了

2.1、gcc编译的四个步骤 

(10条消息) Linux下gcc命令详解_linux gcc_ENSHADOWER的博客-CSDN博客
预处理:            gcc -E Test.c -o Test.i    # -E选项,可以让编译器在预处理后停止,并输出预处理结果
编译:              gcc -S Test.i -o Test.s    # -S选项,表示在程序编译期间,将我们的代码编译成汇编语言。
汇编:              gcc -c Test.s -o Test.o    # -c选项,表示由汇编器负责将刚才的.s文件编译为目标文件,即计算机所能识别的序列。
链接生成可执行文件: gcc Test.o -o Test         # 将刚才的Test.o文件与C标准输入输出库进行连接,最终生成程序Test可执行文件

2.2、多源文件的编译方法

[假设有两个源文件为test.c和testfun.c]
1. 多个文件一起编译
用法:
gcc testfun.c test.c -o test

作用:将testfun.c和test.c分别编译后链接成test可执行文件。

2. 分别编译各个源文件,之后对编译后输出的目标文件链接
用法:
gcc -c testfun.c -o testfun.o    # 将testfun.c编译成testfun.o
gcc -c test.c -o test.o           # 将test.c编译成test.o
gcc -o testfun.o test.o -o test    # 将testfun.o和test.o链接成test
以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译

2.3、库文件连接

开发软件是需要依赖第三方函数库。
函数库实际上就是一些头文件(.h)和库文件(so、或lib、dll)的集合
虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下;Windows所使用的库文件主要放在Visual Stido的目录下的include和lib,以及系统文件夹下。但也有的时候,我们要用的库不再这些目录下,所以GCC在编译时必须用自己的办法来查找所需要的头文件和库文件。
例如我们的程序test.c是在linux上使用c连接mysql,这个时候我们需要去mysql官网下载MySQL Connectors的C库,下载下来解压之后,有一个include文件夹,里面包含mysql connectors的头文件,还有一个lib文件夹,里面包含二进制so文件libmysqlclient.so
其中inclulde文件夹的路径是/usr/dev/mysql/include,lib文件夹是/usr/dev/mysql/lib
静态库链接时搜索路径顺序:
  1. ld会去找GCC命令中的参数-L
  2. 再找gcc的环境变量LIBRARY_PATH
  3. 再找内定目录 /lib、  /usr/lib、   /usr/local/lib 这是当初compile gcc时写在程序内的
动态链接时、执行时搜索路径顺序:
  1. 编译目标代码时指定的动态库搜索路径
  2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
  4. 默认的动态库搜索路径/lib
  5. 默认的动态库搜索路径/usr/lib
有关环境变量:
  • LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
  • LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径

三、示例

3.1、阶段编译

假设有文件 hello.c,内容如下
#include <stdio.h>int main(void)
{printf("Hello, GetIoT\n");return 0;
}
1、编译 hello.c,默认输出 a.out
gcc hello.c
编译 hello.c 并指定输出可执行文件为 hello
gcc hello.c -o hello
2、只执行预处理,输出 hello.i 源文件
gcc -E hello.c -o hello.i
3、只执行预处理和编译,输出 hello.s 汇编文件
gcc -S hello.c -o hello.s
也可以由 hello.i 文件生成 hello.s 汇编文件
gcc -S hello.i -o hello.s
4、只执行预处理、编译和汇编,输出 hello.o 目标文件
gcc -c hello.c -o hello.o
也可以由 hello.i 或 hello.s 生成目标文件 hello.o:
gcc -c hello.i -o hello.o
gcc -c hello.s -o hello.o
5、由 hello.o 目标文件链接成可执行文件 hello
gcc hello.o -o hello

3.2、使用静态库

创建一个 foo.c 文件,内容如下:
#include <stdio.h>void foo(void)
{printf("Here is a static library\n");
}
将 foo.c 编译成静态库 libfoo.a:
gcc -c foo.c           # 生成 foo.o 目标文件
ar rcs libfoo.a foo.o  # 生成 libfoo.a 静态库
查看文件描述
$ file *
修改 hello.c 文件,调用 foo 函数
#include <stdio.h>
void foo(void);int main(void)
{printf("Hello, GetIoT\n");foo();return 0;
}
编译 hello.c 并链接静态库 libfoo.a(加上 -static 选项)
gcc hello.c -static libfoo.a -o hello
也可以使用  -L  指定库的搜索路径,并使用  -l  指定库名
gcc hello.c -static -L. -lfoo -o hello
运行结果:
$ ./hello
查看 hello 文件描述
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=f20be3e93d3c316877bbe4292f5ee7e06cf77f27, for GNU/Linux 3.2.0, not stripped

3.3、使用共享库

修改 foo.c 文件,内容如下
#include <stdio.h>void foo(void)
{printf("Here is a shared library\n");
}
将其编译为动态库/共享库(由于动态库可以被多个进程共享加载,所以需要使用 -fPIC 选项生成位置无关的代码
gcc foo.c -shared -fPIC -o libfoo.so
hello.c 代码无需修改,内容仍然如下
#include <stdio.h>
void foo(void);int main(void)
{printf("Hello, GetIoT\n");foo();return 0;
}
编译 hello.c 并链接共享库 libfoo.so
gcc hello.c  libfoo.so -o hello
也可以使用 -L 和 -l 选项指定库的路径和名称
gcc hello.c -L. -lfoo -o hello
但是此时运行 hello 程序失败
$ ./hello
./hello: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
原因是找不到 libfoo.so 共享库
$ ldd hello
linux-vdso.so.1 (0x00007fff5276d000)
libfoo.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcc90fa7000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcc911bd000)
这是因为 libfoo.so 并不在 Linux 系统的默认搜索目录中,解决办法是我们主动告诉系统,libfoo.so 共享库在哪里
方式一 :设置环境变量  LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$(pwd)
将 libfoo.so 所在的当前目录添加到  LD_LIBRARY_PATH  变量,再次执行 hello
$ ./hello
Hello, GetIoT
Here is a shared library
方式二 :使用 rpath 将共享库位置嵌入到程序
gcc hello.c -L. -lfoo -Wl,-rpath=`pwd` -o hello
rpath 即 run path,是种可以将共享库位置嵌入程序中的方法,从而不用依赖于默认位置和环境变量。这里在链接时使用  -Wl,-rpath=/path/to/yours  选项, -Wl  会发送以逗号分隔的选项到链接器,注意逗号分隔符后面没有空格哦。
这种方式要求共享库必须有一个固定的安装路径,欠缺灵活性,不过如果设置了  LD_LIBRARY_PATH ,程序加载时也是会到相应路径寻找共享库的。
方式三 将 libfoo.so 共享库添加到系统路径
sudo cp libfoo.so /usr/lib/
执行程序
$ ./hello
Hello, GetIoT
Here is a shared library
如果 hello 程序仍然运行失败,请尝试执行  ldconfig  命令更新共享库的缓存列表。
此时,再次查看 hello 程序的共享库依赖
$ ldd hello
linux-vdso.so.1 (0x00007ffecfbb1000)
libfoo.so => /lib/libfoo.so (0x00007f3f3f1ad000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3f3efbb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3f3f1d6000)
可以看到 libfoo.so 已经被发现了,其中 /lib 是 /usr/lib 目录的软链接
示例代码可以在  GitHub  找到。

相关文章:

gcc编译

一、GCC简介 GCC&#xff08;GNU Compiler Collection&#xff09;是 GNU 工具链的主要组成部分&#xff0c;是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件&#xff0c;由 Richard Stallman 于 1985 年开始开发。 GCC 原名为 GNU C语言编译器&#xff0c;因为它原本…...

华为云服务器租用费用及CPU性能(1核2G/2核4G/4核8G)

华为云HECS云服务器即云耀云服务器&#xff0c;类似于阿里云和腾讯云的轻量应用服务器&#xff0c;HECS云服务器1核2G配置39.02元一年、2核4G配置99元一年、4核8G配置69.94元3个月&#xff0c;华为云百科分享华为云HECS云服务器租用费用及CPU性能详解&#xff1a; 目录 华为云…...

Redis---事务管道

目录 一、Redis的事务是什么&#xff1f; 1.1 Redis和关系型数据库事务的区别 二、怎么玩Redis事务&#xff1f; 2.1 正常执行&#xff1a; 2.2 放弃事务 2.3 全体连坐 2.4 冤头债主 2.5 watch监控 三、管道 3.1 为什么会引入管道这个概念呢&#xff1f;我们首先来看一…...

Python的内置数据类型(通过故事来学习)

有一天&#xff0c;小李在学习Python语言时&#xff0c;听到了一个关于内置数据类型的故事。 Python内置了很多数据类型&#xff0c;比如整数、浮点数、字符串、布尔值等等。这些数据类型可以帮助我们更方便地处理数据&#xff0c;提高代码的效率。 小李很好奇&#xff0c;就…...

继瑞吉外卖后的又一个项目——SpringBoot+Vue的前后端博客系统

文章目录 博客系统项目介绍前言项目演示前台演示后台演示 组织结构后端组织结构前端组织结构 技术选型前端技术后端技术架构图系统架构图业务架构图 模块介绍前端模块后端模块 环境搭建开发工具开发环境项目运行 未完待续结语 博客系统项目介绍 前言 本项目已开源在Gitee 后端…...

2023暑期实习历程总结

一.前言 Hello 大家好久不见&#xff0c;已经三个月左右没有更新了&#xff0c;那我这三个月在干什么呢&#xff1f;自2023年3月中旬开始到现在五月底这期间接近三个月的时间里&#xff0c;我一直在进行2023暑期实习的投递和面试。这期间投递了包括各大中厂&#xff08;阿里&am…...

UART-STM32

UART-STM32 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发 第一步,开启时钟,把需要用的USART和GPIO的时钟打开 第二步,GPIO初始化,把TX配置成复用输出,RX配置成输入 第三步,配置USART,直接使…...

jetson nano csi摄像头 tensorrt 运行yolov8检测

jetson nano csi摄像头 tensorrt 运行yolov8检测 基于原始onnx模型的tensorrt预测1. 在本地电脑训练环境下将onnx模型导出yolov8 导出onnx 模型2. 在jetson nano下 转换到tensorrt模型配置好环境后 使用trtexec 生成engine3. 使用python3 tensorrt 读取csi摄像头进行预测修改on…...

提升国际品牌影响力:小企业海外网红营销实战指南

在当今数字化时代&#xff0c;小企业们越来越意识到海外市场的巨大潜力。与此同时&#xff0c;海外网红的崛起也为小企业提供了一个独特的机会&#xff0c;通过与他们合作&#xff0c;迅速拓展国际市场并吸引更多目标受众的关注。然而&#xff0c;对于许多小企业来说&#xff0…...

从零开始的力扣刷题记录-第三十九天

力扣每日四题 228. 汇总区间-简单1431. 拥有最多糖果的孩子-简单637. 二叉树的层平均值-简单49. 字母异位词分组-中等总结 228. 汇总区间-简单 题目描述&#xff1a; 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也…...

PDPS教程:机器人工作站导出为JT格式文件操作方法

目录 功能简介 功能注意事项 导出JT格式文件操作 导出JT格式文件查看 功能简介 PDPS软件不仅能够从外部导入JT格式的模型文件&#xff0c;还能够将创建好的机器人工作站/生产线导出为JT格式的模型文件。这个能够导出JT格式文件的功能就是“Export JT”命令。 使用“Expor…...

【面试】为什么Mysql用B+树做索引而不用B-树或红黑树

文章目录 前言一、B树只有叶节点存放数据&#xff0c;其余节点用来索引&#xff0c;而B-树是每个索引节点都会有Data域。二、那么Mysql如何衡量查询效率呢&#xff1f;三、B树相对于红黑树的区别 前言 原因如下&#xff1a; B树能显著减少IO次数&#xff0c;提高效率B树的查询…...

教你如何选择真正有用的防关联指纹浏览器

从事亚马逊、eBay、Shopify等电商平台的卖家都知道&#xff0c;如果我们需要在这些平台上经营多个店铺&#xff0c;需要使用多个账号为店铺进行评价&#xff0c;在Facebook和Instagram上做SEO和广告&#xff0c;通常也需要使用一个防关联指纹浏览器。 防关联指纹浏览器主要解决…...

某程序员哀叹:月薪四五万,却每天极度焦虑痛苦,已有生理性不适,又不敢裸辞,该怎么办?

高薪能买来快乐吗&#xff1f; 来看看这位程序员的哀叹&#xff1a; 实在是扛不住了&#xff0c;每天都在极度焦虑和痛苦中度过&#xff0c;早上起来要挣扎着做心理建设去上班&#xff0c;已经产生生理性的头晕恶心食欲不振。有工作本身的原因&#xff0c;更多是自己心态的问…...

不愧是腾讯出来的,太厉害了...

前段时间公司缺人&#xff0c;也面了许多测试&#xff0c;一开始瞄准的就是中级水准&#xff0c;当然也没指望能来大牛&#xff0c;提供的薪资在15-20k这个范围&#xff0c;来面试的人有很多&#xff0c;但是平均水平真的让人很失望。看了简历很多上面都是写有4年工作经验&…...

2023年上半年系统集成项目管理工程师上午真题及答案解析

1.在( )领域我国远末达到世界先进水平&#xff0c;需要发挥新型国家体制优势&#xff0c;集中政府和市场两方面的力量全力发展。 A.卫星导航 B.航天 C.集成电路 D.高铁 2.ChatGPT 于2022年11月30日发布&#xff0c;他是人工智能驱动( )。 …...

psd文件丢失了怎么恢复?分享原因及对应恢复方法

PSD文件在设计行业中非常重要。但是&#xff0c;不幸的是&#xff0c;有时这些文件可能会因多种原因而丢失。那么在未备份PSD文件的情况下&#xff0c;PSD文件丢失了怎么恢复呢&#xff1f;如果您遇到了这种问题&#xff0c;不要惊慌&#xff0c;在本篇文章中&#xff0c;我们将…...

【Netty】 工作原理详解(十一)

文章目录 前言一、Netty 模型二、代码示例2.1、引入Maven依赖2.2、服务端的管道处理器2.3、服务端主程序2.4、客户端管道处理器2.5、客户端主程序2.6、测试运行 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设计&#xff08;二&…...

SQL面试必备:100道高频考题解析

前言 在众多IT职场中&#xff0c;SQL技术一直是一个非常重要的技能点。如果你正在准备SQL相关的面试&#xff0c;那么这份“SQL面试 100 问”绝对是你不能错过的宝藏&#xff01; 这份清单涵盖了100道高频考题&#xff0c;从基础知识到复杂应用都有所涉及&#xff0c;帮助你全…...

基于区域的图像分割

文章目录 基于区域的图像分割基本原理常用的算法实现步骤示例代码结论 基于区域的图像分割 基于区域的图像分割是数字图像处理中常用的一种方法&#xff0c;它通过将图像中的像素分配到不同的区域或对象来实现图像分割的目的。相比于基于边缘或阈值的方法&#xff0c;基于区域…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...