• [专题汇总] 【干货合集】7月份的干货合集来了,全面提示就看这里。
    炎热的天气不能影响学习技术的热情,7月份干货合集来了 ,希望可以帮到大家。1.详解MySQL中乐观锁与悲观锁的实现机制及应用场景https://bbs.huaweicloud.com/forum/thread-0232188895402649026-1-1.html2.C++寻位映射的究极密码:哈希扩展-转载https://bbs.huaweicloud.com/forum/thread-0288188731723925024-1-1.html3.【初阶数据结构】双向链表-转载https://bbs.huaweicloud.com/forum/thread-0278188731637851025-1-1.html4. 通俗易懂->哈希表详解-转载https://bbs.huaweicloud.com/forum/thread-02127188731515830029-1-1.html5.数组去重性能优化:为什么Set和Object哈希表的效率最高 -转载https://bbs.huaweicloud.com/forum/thread-0228188731443765029-1-1.html6.【数据结构】时间复杂度和空间复杂度-转载https://bbs.huaweicloud.com/forum/thread-0232188731388663024-1-1.html7.【HarmonyOS Next之旅】DevEco Studio使用指南(三十五) -> 配置构建(二)-转载https://bbs.huaweicloud.com/forum/thread-0278188730852978024-1-1.html8.在【k8s】中部署Jenkins的实践指南-转载https://bbs.huaweicloud.com/forum/thread-0255188730734591030-1-1.html9.Linux下CUDA安装全攻略 -转载https://bbs.huaweicloud.com/forum/thread-0228188730644737028-1-1.html10.Spring Boot 中的默认异常处理机制及执行流程【转载】https://bbs.huaweicloud.com/forum/thread-0228188730601126027-1-1.html11.MyBatis-Plus 自动赋值实体字段最佳实践指南【转载】https://bbs.huaweicloud.com/forum/thread-0278188730544024023-1-1.html12.【Linux】网络基础-转载https://bbs.huaweicloud.com/forum/thread-02127188730499410027-1-1.html13.一文详解php、jsp、asp和aspx的区别(小科普)【转载】https://bbs.huaweicloud.com/forum/thread-0278188730481700022-1-1.html14.如何使用Ajax完成与后台服务器的数据交互详解【转载】https://bbs.huaweicloud.com/forum/thread-0201188730427989026-1-1.html15.【Linux指南】Linux系统 -权限全面解析 -转载https://bbs.huaweicloud.com/forum/thread-0223188730394113017-1-1.html
  • [案例共创] 开发者空间 AI Agent 开发 - 基于 Versatile AI原生应用引擎的《系统编程》智能助教
    案例介绍本案例基于 Versatile AI原生应用引擎的搭建《系统编程》智能助教。1 概述1.1 案例介绍Versatile AI原生应用引擎提供了丰富的AI Agent的支撑功能。本案例基于DeepSeek模型、知识库,搭建了一个简单的Agent,用于承担深圳大学《系统编程》课程助教的角色。其中:DeepSeek模型:利用出色的上下文推理能力和深度思考功能,解答学生的问题。知识库:存储了《系统编程》课程的讲义、示例代码和参考资料,用于增强输出内容的专业性、与课堂知识和案例的相关性,并缓解模型幻觉问题。1.2 适用对象高校师生社区开发者1.3 案例时间本案例总时长预计60分钟。1.4 案例流程用户提出问题;Agent向知识库请求相关的知识;Agent获取相关知识后,启动DeepSeek的深度思考;Agent向用户正式输出回答。1.5 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)开发者空间 AI AgentDeepSeek-R1060 2 知识库配置2.1 进入Versatile AI原生应用引擎界面,点击知识库配置《系统编程》课程所需要的资料。  2.2 点击创建知识库。  2.3 点击创建知识库,并按照如下方法创建配置知识库基础配置  数据接入  数据加工  创建索引配置注意:此处有vectorRAG和GraphRAG两种类型,分别使用向量数据库和知识图谱存储知识。笔者选择了向量数据库的方式。将文本转换成向量,不可避免要用到embedding模型(向量化模型),而平台已经为我们准备好了。   至此,知识库已经做好。   3 Agent开发3.1 返回Versatile AI原生应用引擎界面,点击右上角创建Agent。  3.2 返回Versatile AI原生应用引擎界面,点击右上角创建Agent,并按照下图,设置名称、描述、模型选择、角色设定、知识库、记忆、开场白、推荐问题等选项。然后保存并发布。  3.3 选择发布渠道和设置在发布密钥选择发布渠道:渠道有二:1)以API的形式调用;2)以Web URL的形式访问。本案例选择后者,并以此URL向学生用户开放。设置发布秘钥:请参考文档获取。最后,点击右上角发布。  发布需要等待一小会:  获得如下情况,即可说明成功发布!  4 实际效果智能助教曹老板,在用户提问后,首先查阅资料,然后深度思考,最后给出解答。   我是华为开发者布道师学生曹弈轩,正在参加【案例共创】第5期 开发者空间 AI Agent 开发  cid:link_0
  • 【Linux指南】压缩、网络传输与系统工具-转载
    引言在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛。当我们需要备份海量数据以节省存储资源时,tar与zip等压缩工具能将文件体积大幅缩减;当需要在不同服务器间传输文件时,scp和rz/sz提供了安全高效的传输方案;而top、sar等系统工具则能实时洞悉服务器的运行状态,帮助管理员提前发现性能瓶颈。本文将系统解析压缩解压的核心技术、跨设备文件传输的最佳实践,以及系统资源监控的全流程方案,帮助读者构建从数据压缩到远程管理的完整技能体系。一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作(1)zip压缩命令# 压缩单个文件zip 压缩包名.zip 文件名# 示例:压缩配置文件zip config.zip config.ini# 压缩目录(需加-r参数)zip -r 压缩包名.zip 目录名# 示例:压缩整个项目目录zip -r project.zip project/# 压缩时排除指定文件zip -r project.zip project/ -x "project/temp/*"# 压缩并显示进度zip -rq project.zip project/ &> /dev/null && echo "压缩完成"核心参数:-r(recursive):递归压缩目录及其内容-q(quiet):静默压缩,不显示过程-x(exclude):排除指定文件或目录-z:添加压缩说明-m:压缩后删除源文件(2)unzip解压命令# 解压到当前目录unzip 压缩包名.zip# 示例:解压配置文件包unzip config.zip# 解压到指定目录(-d参数)unzip 压缩包名.zip -d 目标目录# 示例:解压到backup目录unzip project.zip -d backup/# 查看压缩包内容(不解压)unzip -l 压缩包名.zip# 解压时覆盖文件不询问unzip -o 压缩包名.zip实用技巧:批量解压多个zip包:for f in *.zip; do unzip $f; done选择性解压:unzip project.zip "src/*.java"密码保护压缩包:zip -r -P password secure.zip sensitive_data/(注:zip密码保护强度较低,不建议用于敏感数据)2. tar:专业备份工具的终极方案注意:日常生活中我们一般都是说打包压缩,事实上,打包和压缩是两码事而对于tar来说,就将此区分开来,打包的文件后缀为.tar,压缩后的文件为.gz打包压缩后的文件为 .tar.gz 一般也简写为.tgz(1)tar打包压缩语法# 基本语法:tar [选项] 归档文件名 源文件/目录# 示例1:打包目录(不压缩)tar -cvf project.tar project/# 示例2:打包并压缩为tgz格式(gzip压缩)tar -czvf project.tgz project/# 示例3:打包并压缩为tbz2格式(bzip2压缩,压缩率更高)tar -cjvf project.tbz2 project/# 示例4:打包并压缩为txz格式(xz压缩,压缩率最高)tar -cJvf project.txz project/(2)tar解压命令# 解压tgz文件到当前目录tar -xvzf project.tgz# 解压到指定目录(-C参数)tar -xvzf project.tgz -C /backup/# 查看归档文件内容tar -tvf project.tar# 解压时排除指定文件tar -xvzf project.tgz --exclude "project/logs/*"(3)核心选项解析打包选项:-c(create):创建归档文件-v(verbose):显示详细过程-f(file):指定归档文件名(必须放在选项最后)压缩选项:-z:使用gzip压缩(.tar.gz或.tgz)-j:使用bzip2压缩(.tar.bz2)-J:使用xz压缩(.tar.xz)解压选项:-x(extract):解压归档文件-C(directory):指定解压目录--strip n:解压时移除n层目录结构3. 压缩工具对比与场景选择工具    压缩格式    压缩率    速度    适用场景zip    .zip    中    快    通用文件压缩、跨平台传输gzip    .gz    中    快    单文件压缩、日志归档bzip2    .bz2    高    中    备份文件、长期存储xz    .xz    极高    慢    归档压缩、节省存储空间tar    .tar    无    极快    仅打包不压缩的场景4. 压缩实战:日志归档与备份策略(1)按日期归档日志# 归档今天的日志并压缩tar -czvf access_log_$(date +%Y%m%d).tgz /var/log/access.log# 保留7天日志,自动删除过期归档find /backup/logs -name "access_log_*.tgz" -mtime +7 -exec rm {} \;(2)增量备份方案# 首次全量备份tar -czvf full_backup.tgz /data/# 后续增量备份(仅备份变化文件)rsync -avz --delete /data/ /data_backup/tar -czvf incremental_$(date +%Y%m%d).tgz /data_backup/(3)跨服务器压缩传输# 压缩并远程传输(一行命令完成)tar -czf - /data/ | ssh user@remote "cat > /backup/data_$(date +%Y%m%d).tgz"AI写代码bash12二、网络传输:跨设备文件交互的桥梁1. scp:安全拷贝的跨服务器传输(1)基本传输语法# 从本地复制到远程scp 本地文件/目录 user@远程IP:远程路径# 示例:上传文件到远程服务器scp config.ini root@192.168.1.100:/etc/# 从远程复制到本地scp user@远程IP:远程文件/目录 本地路径# 示例:下载远程日志文件scp root@192.168.1.100:/var/log/access.log ./# 递归复制目录(-r参数)scp -r 本地目录 user@远程IP:远程目录(2)高级传输选项# 指定SSH端口(-P参数,注意大写)scp -P 2222 config.ini root@192.168.1.100:/etc/# 显示传输进度(-v参数)scp -v big_file.iso user@remote:/backup/# 压缩传输减少带宽占用(-C参数)scp -C large_directory/ user@remote:/backup/8(3)免密传输配置# 1. 本地生成密钥对ssh-keygen -t rsa# 2. 将公钥复制到远程服务器ssh-copy-id user@remoteIP# 3. 免密传输示例scp config.ini user@remote:/etc/  # 无需输入密码2. rz/sz:交互式文件传输(1)rz:上传文件到服务器# 在终端中执行rz命令,弹出文件选择对话框rz# 示例:上传代码包到当前目录rz project.zip# 指定上传目录rz -e -y -p /data/(2)sz:从服务器下载文件# 下载单个文件sz 文件名# 示例:下载配置文件到本地sz /etc/httpd.conf# 下载多个文件sz file1.txt file2.log# 递归下载目录(需配合tar)tar -czf - directory/ | sz -(3)工具安装与配置# CentOS/RHEL安装rz/szyum install -y lrzsz# 配置rz/sz默认路径(修改~/.bashrc)export RZ_SZ_PATH="/downloads"source ~/.bashrc3. 传输工具对比与场景选择工具    协议    交互性    跨平台    大文件支持    适用场景scp    SSH    非交互    是    好    脚本自动化传输、安全传输rz/sz    Zmodem    交互    部分    一般    终端交互式上传下载rsync    SSH    非交互    是    极好    增量同步、远程备份ftp/sftp    FTP/SFTP    交互    是    好    传统文件服务器、多用户共享4. 网络传输安全与性能优化(1)安全传输实践避免使用明文传输协议(如ftp),优先使用scp/sftp定期更新服务器SSH密钥,防止中间人攻击对敏感数据先加密再传输:gpg -c sensitive_data.txt && scp sensitive_data.txt.gpg remote:(2)大文件传输优化使用rsync替代scp进行大文件增量传输:rsync -avzP --progress big_file.iso user@remote:/backup/分割文件传输后合并:# 分割文件(每个1GB)split -b 1G big_file.iso part_# 传输分割文件scp part_* user@remote:/backup/# 远程合并文件cat /backup/part_* > /backup/big_file.iso利用多线程传输工具(如aria2):aria2c -x 16 scp://user@remote/path/to/big_file.isoAI写代码bash1三、系统状态监控:服务器健康的全方位诊断1. top:实时系统监控(1)基础监控界面# 启动top进入实时监控top(2)界面解析系统概况行:top - 15:30:22 up 1 day, 23:50, 2 users, load average: 0.15, 0.20, 0.25分别为:时间、运行时间、用户数、1/5/15分钟平均负载CPU使用行:Cpu(s):  0.5%us,  0.3%sy,  0.0%ni, 99.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%stus:用户空间CPU,sy:内核空间,id:空闲,wa:I/O等待内存使用区:Mem:   16384M total,  15232M used,   1152M free,    768M buffersSwap:  32768M total,      0M used,  32768M free,   8960M cached进程列表区:PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND1   root      20   0    4880    340    280 S   0.0  0.0   0:01.20 systemd(3)交互操作P:按CPU占用排序M:按内存占用排序N:按PID排序k:输入PID终止进程f:自定义显示字段t:切换到CPU/内存/进程树视图2. sar:系统活动的历史记录仪(1)CPU性能监控# 查看当前CPU利用率(每1秒采样,共5次)sar -u 1 5# 查看历史CPU数据(昨天10点到12点)sar -u -f /var/log/sa/sa28 -s 10:00 -e 12:00(2)内存与swap监控# 查看内存使用情况sar -r 2 3# 查看swap使用情况sar -W 2 3(3)磁盘I/O监控# 查看磁盘读写速率sar -d 3 2# 查看top 5繁忙磁盘sar -d -o disk_sar 3 100sar -d -f disk_sar | sort -k 5 -nr | head -n 53. 系统资源查看:free、df、netstat(1)内存查看:free# 查看内存使用(默认单位KB)free# 以MB为单位显示free -m# 显示详细内存统计free -h -t(2)磁盘查看:df# 查看磁盘空间使用df# 以人类可读格式显示df -h# 查看指定目录的磁盘占用df -h /data/(3)网络查看:netstat# 查看所有网络连接netstat -an# 查看TCP连接状态netstat -ant | grep ESTABLISHED# 查看监听端口netstat -tuln4. 性能分析实战:定位系统瓶颈(1)CPU高负载排查# 1. 用top定位高CPU进程top# 2. 查看进程详细信息ps -ef | grep 高CPU进程PID# 3. 分析进程资源占用pmap 进程PID# 4. 查看进程线程状态top -H -p 进程PID(2)内存泄漏检测# 1. 监控内存变化趋势watch -n 5 'free -m | grep Mem'# 2. 查看内存占用前10的进程ps -eo pid,ppid,user,%mem,%cpu,comm | sort -k4 -nr | head -n 10# 3. 使用valgrind分析程序内存泄漏valgrind --leak-check=full ./program(3)网络拥堵分析# 1. 查看网络接口流量iftop -i eth0# 2. 分析TCP连接状态netstat -ant | awk '{print $6}' | sort | uniq -c | sort -nr# 3. 追踪网络延迟tracepath www.example.com四、系统管理工具:服务器控制的终极手段1. uname:系统信息的全景扫描(1)基本系统信息# 查看所有系统信息uname -a# 输出示例:# Linux localhost.localdomain 5.4.0-124-generic #140-Ubuntu SMP Fri Mar 24 14:29:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux(2)分项信息查看# 查看内核版本uname -r# 查看系统架构uname -m# 查看主机名uname -n# 查看操作系统类型uname -s(3)扩展系统信息# 查看Linux发行版信息cat /etc/os-release# 查看CPU信息lscpu# 查看硬件信息dmidecode2. shutdown:系统开关机的安全控制注意:Linux系统作为服务器使用,如非必要,不建议关机(1)关机操作# 立即关机(root权限)shutdown -h now# 10分钟后关机shutdown -h +10 "系统即将关机,请保存工作"# 取消关机shutdown -c(2)重启操作# 立即重启shutdown -r now# 定时重启shutdown -r 22:00 "夜间例行重启"(3)其他关机命令# 立即关机(简化命令)halt# 立即重启(简化命令)reboot# 关闭系统但不切断电源poweroff3. bc:命令行计算器的科学计算(1)基本计算# 启动bc计算器bc# 示例计算:10 + 2030 * 4100 / 35 ^ 2  # 5的平方sqrt(16)  # 平方根(2)表达式计算# 直接计算表达式(无需进入交互模式)echo "100 * 3.14" | bc# 计算分数结果echo "scale=2; 1/3" | bc  # scale指定小数位数# 计算复杂表达式echo "((2+3)*4-5)/2" | bc3)高级数学函数# 启用数学库(-l参数)bc -l# 示例函数:sin(1)    # 正弦函数cos(1)    # 余弦函数log(10)   # 自然对数exp(1)    # 指数函数五、扩展知识:压缩与系统工具的深度实践1. 压缩原理与算法选择(1)压缩核心概念无损压缩:还原后数据与原始完全一致(如zip、tar.gz)有损压缩:还原后有数据损失(如jpg、mp3,不用于系统文件)压缩率与速度权衡:xz > bzip2 > gzip > zip,速度反之(2)算法特点对比gzip:平衡压缩率与速度,适用于日志归档、临时压缩bzip2:较高压缩率,适用于备份文件、长期存储xz:最高压缩率,适合归档极少访问的历史数据zip:跨平台支持好,适合通用文件压缩传输2. 系统监控最佳实践(1)监控指标阈值设置CPU利用率:长期超过80%需关注内存空闲:低于10%需排查内存泄漏磁盘空间:剩余空间低于20%需清理网络带宽:利用率超过70%需扩容(2)自动化监控脚本# 定时监控系统状态并发送告警#!/bin/bash# 监控指标cpu_usage=$(top -bn1 | grep "Cpu" | awk '{print $2}' | cut -d'%' -f1)mem_free=$(free -m | grep Mem | awk '{print $4}')disk_free=$(df -h | grep / | awk '{print $4}' | cut -d% -f1)# 告警阈值cpu_warn=80mem_warn=100disk_warn=20# 发送告警邮件if [ $(echo "$cpu_usage > $cpu_warn" | bc -l) -eq 1 ]; then    echo "CPU高负载: $cpu_usage%" | mail -s "系统告警" admin@example.comfi# 更多指标监控...3. 实战案例:服务器完整备份与迁移案例:服务器数据迁移方案# 1. 压缩源服务器数据tar -czvf data_backup.tgz /data/ /config/# 2. 传输到目标服务器scp data_backup.tgz root@new_server:/backup/# 3. 解压并验证ssh root@new_server "tar -xvzf /backup/data_backup.tgz -C /"# 4. 同步系统配置rsync -avzP --exclude "data/" root@old_server:/etc/ /etc/# 5. 启动服务并检查systemctl restart all-servicestop -15结语通过掌握压缩、网络传输与系统监控的核心工具,读者将能够高效管理服务器数据生命周期,从本地压缩归档到跨服务器安全传输,再到系统运行状态的实时监控与性能优化。无论是tar的专业备份方案,scp的安全远程传输,还是top与sar的多维性能分析,这些工具的灵活运用将成为Linux系统管理员的核心竞争力。在实际运维中,建议结合自动化脚本与监控平台,建立完善的数据备份策略与系统健康检查机制,确保服务器稳定高效运行。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/2302_78391795/article/details/148311922
  • [技术干货] Linux下CUDA安装全攻略 -转载
    在当今的高性能计算和人工智能领域,CUDA(Compute Unified Device Architecture)已经成为不可或缺的技术。它是由NVIDIA推出的并行计算平台和编程模型,能够充分利用NVIDIA GPU的强大计算能力,为各种计算密集型任务提供加速。本文将详细介绍在Linux系统下安装CUDA的全过程,包括概念讲解、安装步骤、代码示例、应用场景、注意事项以及相关架构图和流程图,帮助读者快速上手并掌握CUDA的使用。一、CUDA简介(一)什么是CUDACUDA是一种并行计算平台和编程模型,它允许开发者使用C、C++、Fortran等常见的编程语言编写程序,并将这些程序运行在NVIDIA的GPU上。通过CUDA,开发者可以充分利用GPU的多核架构,实现大规模并行计算,从而显著提高计算效率。(二)CUDA的优势强大的并行计算能力:GPU拥有成千上万个核心,能够同时处理大量任务,这使得CUDA在处理大规模数据和复杂计算时具有显著优势。与NVIDIA硬件紧密结合:CUDA专为NVIDIA的GPU设计,能够充分利用硬件的特性,提供高效的计算性能。广泛的生态系统:CUDA拥有丰富的库和工具,如cuBLAS、cuFFT等,为开发者提供了强大的支持。跨平台支持:CUDA不仅支持Linux系统,还支持Windows和macOS,开发者可以在不同的操作系统上开发和运行CUDA程序。(三)CUDA的架构CUDA的架构主要由以下几个部分组成:主机(Host):主机是指运行CUDA程序的CPU,它负责管理程序的执行流程和内存分配。设备(Device):设备是指NVIDIA的GPU,它负责执行并行计算任务。CUDA内核(Kernel):CUDA内核是运行在GPU上的函数,它由主机调用,并在设备上执行。内存空间:CUDA支持多种内存空间,包括全局内存、共享内存和寄存器等,开发者可以根据需要选择合适的内存类型。二、CUDA安装前的准备在安装CUDA之前,需要确保系统满足以下条件:(一)硬件要求NVIDIA GPU:CUDA仅支持NVIDIA的GPU,因此需要确保系统中安装了支持CUDA的NVIDIA显卡。可以通过访问NVIDIA官方网站查询支持CUDA的GPU型号。 在 https://developer.nvidia.com/cuda-gpus 查看 GPU 是否支持CUDA。兼容的主板和电源:确保主板支持NVIDIA显卡,并且电源能够提供足够的功率以满足显卡的需求。(二)软件要求Linux操作系统:CUDA支持多种Linux发行版,如Ubuntu、CentOS等。本文将以Ubuntu为例进行说明。uname -m && cat /etc/*releasex86_64DISTRIB_ID=UbuntuDISTRIB_RELEASE=22.07AI写代码gcc --versiongcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0AI写代码驱动程序:需要安装最新版本的NVIDIA驱动程序,驱动程序版本需要与CUDA版本兼容。可以通过访问NVIDIA官方网站下载并安装驱动程序。 https://developer.nvidia.com/cuda-gpus 注意选择正确版本如果您之前安装过 CUDA(例如为12.1版本),需要先使用 sudo /usr/local/cuda-12.1/bin/cuda-uninstaller 卸载。如果该命令无法运行,可以直接:sudo rm -r /usr/local/cuda-12.1/sudo apt clean && sudo apt autocleanAI写代码卸载完成后运行以下命令并根据提示继续安装:wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.runsudo sh cuda_12.2.0_535.54.03_linux.runAI写代码注意:在确定 CUDA 自带驱动版本与 GPU 是否兼容之前,建议取消 Driver 的安装。完成后输入 nvcc -V 检查是否出现对应的版本号,若出现则安装完成。开发工具:需要安装C/C++编译器(如gcc)和make工具,这些工具用于编译CUDA程序。(三)安装步骤更新系统:在安装CUDA之前,建议先更新系统,以确保系统中的软件包是最新的。可以使用以下命令更新系统sudo apt updatesudo apt upgradeAI写代码安装NVIDIA驱动程序:可以通过访问NVIDIA官方网站下载驱动程序安装包,并按照说明进行安装。安装完成后,可以通过以下命令验证驱动程序是否安装成功nvidia-smiAI写代码如果安装成功,将显示驱动程序版本和GPU状态。三、CUDA安装过程(一)下载CUDA安装包访问NVIDIA官方网站的CUDA下载页面,选择适合的CUDA版本和操作系统版本。CUDA版本需要与NVIDIA驱动程序版本兼容,否则可能会出现兼容性问题。下载CUDA安装包,安装包通常是一个.run文件或一个.deb文件。(二)安装CUDA安装.run文件:如果下载的是.run文件,可以通过以下命令安装CUDAsudo chmod +x cuda_installer.runsudo ./cuda_installer.runAI写代码在安装过程中,需要根据提示进行操作,包括接受许可协议、选择安装路径等。安装.deb文件:如果下载的是.deb文件,可以通过以下命令安装CUDAsudo dpkg -i cuda-repo-<distro>_<version>_amd64.debsudo apt updatesudo apt install cudaAI写代码其中<distro>表示Linux发行版,<version>表示CUDA版本。(三)配置环境变量安装完成后,需要配置环境变量,以便能够正确使用CUDA。可以将以下内容添加到~/.bashrc文件中:export PATH=/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATHAI写代码然后执行以下命令使环境变量生效:source ~/.bashrcAI写代码(四)验证CUDA安装可以通过运行以下命令验证CUDA是否安装成功:nvcc --versionAI写代码如果安装成功,将显示CUDA版本信息。四、CUDA开发环境搭建(一)安装CUDA ToolkitCUDA Toolkit是CUDA开发的核心工具,它提供了编译器、调试器、性能分析工具等。可以通过以下命令安装CUDA Toolkit:sudo apt install cuda-toolkitAI写代码(二)安装CUDA驱动程序CUDA驱动程序是CUDA运行的基础,它负责管理GPU的硬件资源。可以通过以下命令安装CUDA驱动程序:sudo apt install nvidia-cuda-toolkitAI写代码(三)安装CUDA运行时库CUDA运行时库是CUDA程序运行时所需的库文件,可以通过以下命令安装CUDA运行时库:sudo apt install libcudart7AI写代码(四)安装CUDA示例程序CUDA示例程序可以帮助开发者快速了解CUDA的编程模型和开发流程。可以通过以下命令安装CUDA示例程序:sudo apt install cuda-samplesAI写代码五、CUDA编程基础(一)CUDA程序结构CUDA程序通常由主机代码和设备代码组成。主机代码运行在CPU上,负责管理程序的执行流程和内存分配;设备代码运行在GPU上,负责执行并行计算任务。(二)CUDA内核函数CUDA内核函数是运行在GPU上的函数,它由主机调用,并在设备上执行。内核函数的定义方式与普通C函数类似,但需要使用__global__关键字修饰。(三)CUDA内存管理CUDA提供了多种内存管理方式,包括全局内存、共享内存和寄存器等。开发者可以根据需要选择合适的内存类型,以提高程序的性能。(四)代码示例以下是一个简单的CUDA程序示例,它实现了向量加法运算:#include <stdio.h> __global__ void vector_add(int *a, int *b, int *c, int n) {    int index = threadIdx.x + blockIdx.x * blockDim.x;    if (index < n) {        c[index] = a[index] + b[index];    }} int main() {    int n = 1024;    int *a, *b, *c;    int *d_a, *d_b, *d_c;     // 分配主机内存    a = (int *)malloc(n * sizeof(int));    b = (int *)malloc(n * sizeof(int));    c = (int *)malloc(n * sizeof(int));     // 初始化主机内存    for (int i = 0; i < n; i++) {        a[i] = i;        b[i] = i;    }     // 分配设备内存    cudaMalloc((void **)&d_a, n * sizeof(int));    cudaMalloc((void **)&d_b, n * sizeof(int));    cudaMalloc((void **)&d_c, n * sizeof(int));     // 将数据从主机内存复制到设备内存    cudaMemcpy(d_a, a, n * sizeof(int), cudaMemcpyHostToDevice);    cudaMemcpy(d_b, b, n * sizeof(int), cudaMemcpyHostToDevice);     // 调用CUDA内核函数    int blockSize = 256;    int numBlocks = (n + blockSize - 1) / blockSize;    vector_add<<<numBlocks, blockSize>>>(d_a, d_b, d_c, n);    // 将结果从设备内存复制到主机内存    cudaMemcpy(c, d_c, n * sizeof(int), cudaMemcpyDeviceToHost);     // 输出结果    for (int i = 0; i < n; i++) {        printf("%d + %d = %d\n", a[i], b[i], c[i]);    }     // 释放内存    free(a);    free(b);    free(c);    cudaFree(d_a);    cudaFree(d_b);    cudaFree(d_c);     return 0;}AI写代码该程序首先在主机上分配内存并初始化数据,然后将数据从主机内存复制到设备内存,接着调用CUDA内核函数在设备上执行向量加法运算,最后将结果从设备内存复制回主机内存并输出。六、CUDA应用场景(一)深度学习CUDA在深度学习领域得到了广泛应用,许多深度学习框架如TensorFlow、PyTorch等都支持CUDA加速。通过CUDA,可以显著提高神经网络的训练和推理速度,从而加速深度学习模型的开发和部署。(二)科学计算CUDA在科学计算领域也具有重要应用,例如在物理模拟、化学计算、生物信息学等领域。通过CUDA,可以利用GPU的强大计算能力,快速处理大规模数据和复杂计算任务,提高科学研究的效率。(三)图像处理CUDA在图像处理领域也有广泛应用,例如在图像识别、图像增强、图像分割等方面。通过CUDA,可以实现高效的图像处理算法,提高图像处理的速度和质量。(四)金融计算CUDA在金融计算领域也具有重要应用,例如在风险评估、投资组合优化、金融市场模拟等方面。通过CUDA,可以快速处理大量金融数据,提高金融计算的效率和准确性。七、CUDA安装注意事项(一)驱动程序版本兼容性CUDA版本需要与NVIDIA驱动程序版本兼容,否则可能会出现兼容性问题。在安装CUDA之前,需要确保驱动程序版本与CUDA版本兼容。(二)安装路径选择在安装CUDA时,可以选择默认的安装路径(通常是/usr/local/cuda),也可以选择自定义安装路径。如果选择自定义安装路径,需要确保环境变量配置正确。(三)依赖包安装在安装CUDA时,需要确保系统中安装了所有必要的依赖包,否则可能会出现安装失败或运行错误。可以通过运行以下命令安装依赖包:sudo apt install build-essentialAI写代码(四)CUDA版本选择在安装CUDA时,需要根据实际需求选择合适的CUDA版本。不同版本的CUDA在功能和性能上可能存在差异,需要根据实际需求进行选择。八、总结本文详细介绍了在Linux系统下安装CUDA的全过程,包括概念讲解、安装步骤、代码示例、应用场景、注意事项以及相关架构图和流程图。通过本文的介绍,读者可以快速掌握CUDA的安装和使用方法,为后续的并行计算开发打下坚实的基础。CUDA作为一种强大的并行计算平台,具有广泛的应用前景,希望本文能够对读者有所帮助。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/csdn122345/article/details/147722895
  • [技术干货] 【Linux】网络基础-转载
    一、TCP/IP五层模型为什么要有TCP/IP?单个计算机内部,硬件和硬件之间通过线路直接连接完成通信,那两台相隔长距离的计算机之间也会需要通信。而长距离通信的数据传输,又会有以下问题:靠什么传播?传播到哪里(目的地)?传到目的地之间要经过哪里?传播过程中出现丢包(错误)?传到了以后,怎么处理?TCP/IP就是针对上述问题的解决长距离传输问题的解决方案!TCP/IP五层模型是网络通信的框架(所有OS都要遵守,是标准),它将复杂的网络通信过程分为五个层次,每一层都有特定的功能。 下面用通俗易懂的方式介绍每一层的作用,并举例说明:1. 物理层(Physical Layer)作用:负责实际的比特流(0和1)传输,通过物理介质(如电缆、光纤、无线电波)传递信号。例子:就像快递员搬运包裹时使用的“交通工具”(卡车、飞机、自行车),物理层就是网络数据的“车轮”,负责把数据从A点搬到B点。比如你家的Wi-Fi信号、网线的电流、光纤里的光脉冲都属于这一层。2. 数据链路层(Data Link Layer)作用:将比特流组织成“帧”(Frame),并检查传输错误(如丢包、干扰)。通过MAC地址(如00-1A-2B-3C-4D)在局域网内直接通信。例子:就像快递员在小区内送货时,根据“门牌号”(MAC地址)把包裹投递到具体的家庭。比如你家的路由器通过Wi-Fi将数据传给手机时,就是通过MAC地址找到你的设备。3. 网络层(Network Layer)作用:通过IP地址(如192.168.1.1)在不同网络之间路由数据包。核心协议是IP(Internet Protocol)。例子:就像快递公司的“分拣中心”,决定包裹从北京到上海要走哪条高速公路(路由选择)。比如你访问百度时,数据包会经过多个路由器跳转,最终到达百度的服务器。4. 传输层(Transport Layer)作用:确保数据可靠传输(如TCP协议会重传丢失的数据包)或快速传输(如UDP协议)。通过端口号(如80用于网页)区分不同应用程序。例子:就像快递员把包裹送到你家后,还要确认是给“爸爸”(端口443)还是“孩子”(端口80)的。比如你刷视频(UDP)和网上付款(TCP)对可靠性的要求不同,传输层会分别处理。5. 应用层(Application Layer)作用:直接面向用户,提供具体的网络服务(如网页、邮件、文件传输)。例子:就像你使用的“快递服务内容”:网购(HTTP)、发邮件(SMTP)、视频通话(WebRTC)。比如你打开浏览器访问网页时,用的就是HTTP协议(属于应用层)。6. 总结:网购类比物理层:快递卡车在路上跑。数据链路层:卡车司机按“门牌号”(MAC地址)把包裹送到你家小区。网络层:快递公司决定包裹从杭州到北京走哪条路线(IP地址)。传输层:确保包裹完整送到,如果丢了就重发(TCP),或直接扔给你不管是否完整(UDP)。应用层:你拆开包裹,看到买的是一本书(HTTP)或一件衣服(FTP)。这样分层的好处是:每一层只需专注自己的任务,其他层的变化不会影响整体。7. 每层所处的位置 协议所谓协议,就是通信双方都认识的结构化的数据类型(共识)比如一个int占4个字节,因为我们知道它占4个字节,所以我们&拿到最低字节的地址也能访问整个int,这就是一种协议!假设在传输层定义了一个协议(结构体),传输的时候,两台主机都按这个协议标准,则 B 收到 A 发来的结构体,自然就知道里面是什么内容。对于不同的操作系统,他们的网络协议栈一定是一样的8. 广域网和局域网从主机 A 传输到主机 B ,整个过程,靠的是广域网,遵循的是TCP/IP。但是中途,从一个路由器到另一个路由器(或者从一个主机到一个路由器),靠的是局域网(局域网的标准不只一个),广域网可连接多个局域网。二,局域网网络传输流程(以太网为例)1. 认识MAC地址对于每一个主机,在出厂的时候,每个网卡上都会有一个标识唯一的地址——MAC地址(不能修改)MAC地址的特点用来识别数据链路层中相连的节点长度为 48 位, 及 6 个字节. 一般用 16 进制数字加上冒号的形式来表示(例如:08:00:27:03:fb:19)2. 局域网通信当多个主机连接同一个以太网时,一个主机往网络里面发信息,所有主机都能收到。但是,信息中会标识接收主机的mac地址,每个主机将自己的mac地址与之比较。如果相同则处理信息,不相同则丢弃信息。 以太网有以下规定:以太网中,任何时刻,只允许一台机器向网络中发送数据(类似:线程互斥)如果有多台同时发送,会发生数据干扰,我们称之为数据碰撞所有发送数据的主机要进行碰撞检测和碰撞避免比如,碰撞检测发现碰撞了,就sleep等一下发(碰撞避免)没有交换机的情况下,一个以太网就是一个碰撞域局域网通信的过程中,主机对收到的报文确认是否是发给自己的,是通过目标mac地址判定其他局域网无限LAN的原理和以太网相同,不过是无线。令牌环网的原理:只允许拿着令牌的主机发(互斥锁)3. 以两台主机通信为例当两台主机在以太网内通信,实际上,发送信息的是协议栈的应用层。在网络传输的过程中,数据不是直接发送给对方主机的,而是先要自定向下将数据交付给下层协议,最后由底层发送,然后由对方主机的底层来进行接受,在自底向上进行向上交付数据要通过协议栈发送到网络上,(自顶向下时)每层协议都要加上一个数据首部(本协议层的报头),我们称为封装首部信息中包含了一些类似于首部有多长, 载荷(payload)有多长, 上层协议是什么等信息数据到达目标主机以后,(自底向上时)每层协议再剥掉相应的首部(解包),根据首部中的 “上层协议字段” 将数据交给对应的上层协议处理(分用)除了报头,剩下的叫做有效载荷报文 = 报头 + 有效载荷任何一层都只关注自己层的报头(都认为自己在和对方同层的协议直接通信,实际上是经过了自顶向下的封包和自底向上的解包和分用的)数据封装数据解包三,跨网络传输流程1. 认识IP地址IP地址是分配给连接到计算机网络的设备的唯一标识符比如两个主机连接了同一个WIFI,则会被分配对应的IP地址(内网IP),它是设备在网络中的 “门牌号”IP 协议有两个版本, IPv4 和 IPv6(默认指IPv4)IPv4 来说, IP 地址是一个 4 字节, 32 位的整数。例如 192.168.0.1,用点分割的每一个数字表示一个字节, 范围是 0 - 255我们可以把IP地址看做是“最终地址”(逻辑地址),而MAC地址是“下一站地址”(物理地址)IP地址网络层有效,MAC地址数据链路层有效2. 跨网络传输流程跨网段的主机的数据传输。数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器。以下图为例,A 的数据要通过以太网和令牌网两个不同的网才能传到B。首先,用户 A 的数据经过层层封包到了网络层,网络层给数据加上 IP 头部src(源IP):192.168.2.2(用户 A 的局域网 IP)dst(目标IP):172.168.2.2(用户 B 的 IP,属于另一个网段,通过前缀判断)然后,主机 A 网络层对比目标 IP 和自身所在的网段,发现:数据不是发给本网段主机的,必须通过路由器转发到其他网段如果发现和自身所在网段相同,那其实就是往局域网里发所以,网络层数据需要向下传递到数据链路层,封装MAC头部源MAC:主机A的目标MAC:路由器的局域网侧 MAC接着,数据帧会通过 网卡 从主机 A 发送到 路由器(通过 MAC 地址)路由器收到数据帧以后,会解包向上传,在网络层检查目标 IP,发现网段对应的出口是路由器的另一块网卡于是,又会把数据往下传递到数据链路层,重新封装MAC头部源MAC:路由器外网侧网卡的 MAC目标MAC:主机 B 的最后,封装后的数据帧通过路由器外网侧网卡发送,最终到达用户 B 的网卡我们可以发现:目的 IP 是一种长远目标,Mac 是下一阶段目标,目的 IP 是路径选择的重要依据,mac 地址是局域网转发的重要依据————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/tan_run/article/details/148472524
  • [技术干货] 【Linux指南】Linux系统 -权限全面解析 -转载
    一、Linux权限的核心概念1.1 权限的本质:角色与事物属性的结合在Linux系统中,权限的本质可以理解为**“角色对事物的操作许可”**。这里的"角色"决定了谁可以进行操作,而"事物属性"则定义了操作的类型和范围。更通俗地说:权限 = 角色 + 事物属性人 = 真实个体 + 身份角色这种设计使得系统能够以结构化的方式管理访问控制,确保不同身份的用户只能执行其被允许的操作。1.2 Linux中的三类基本角色Linux系统将访问角色划分为三个基本类别,这三类角色构成了权限管理的核心框架:拥有者(Owner):文件或目录的创建者,通常是用户本人所属组(Group):与文件关联的用户组,用于团队协作场景其他用户(Other):系统中除拥有者和所属组外的所有用户在通过ls -l命令查看文件属性时,第三个和第四个字段分别表示拥有者和所属组名称,例如:-rwxr-xr-- 1 user1 dev 1024 Jan 10 08:00 test.txt          ↑    ↑          拥有者 所属组二、用户体系与身份切换2.1 root超级用户与普通用户1. root超级用户拥有系统的最高权限,几乎不受任何权限约束可以访问和修改系统中的任何文件与配置命令行提示符为#,与普通用户形成明显区别2. 普通用户权限受到严格限制,只能访问自己目录下的文件无法修改系统关键配置,需通过提权命令执行特权操作命令行提示符为$2.2 su命令:用户身份切换的核心工具su(switch user)命令用于在不同用户之间切换,其用法和特性如下:基本切换语法su 用户名  # 切换到指定用户,保持当前工作目录su - 用户名 # 切换到指定用户并重新加载环境(相当于登录)切换到root用户su        # 切换到root,需输入root密码su -      # 完整切换到root环境从root切换到普通用户无需密码,直接执行su 用户名即可退出当前用户可使用exit或Ctrl+D重要特性su切换时不会改变工作目录,su -会切换到目标用户的家目录输入密码时不会显示任何字符,这是Linux的安全设计2.3 sudo命令:精准授权的提权方案1. sudo的核心概念全称"superuser do",允许普通用户以特权身份执行命令基于白名单机制(/etc/sudoers)进行授权管理避免直接使用root账户,提高系统安全性2. 基本用法sudo 命令    # 以root权限执行命令sudo -u 用户 命令 # 以指定用户身份执行命令3. 认证机制首次执行sudo时,需输入当前用户密码(验证是否在sudoers白名单)验证通过后,默认15分钟内无需再次输入密码若用户不在白名单,需输入root密码才能执行4. 白名单配置# 以root身份编辑sudoers文件(推荐使用visudo以避免语法错误)visudoAI写代码在文件中添加以下格式的授权规则:用户名 主机名=(目标用户) 命令列表# 示例:允许user1以root身份执行所有命令user1 ALL=(ALL) ALL三、文件权限的表示与管理3.1 文件属性与权限标识通过ls -l命令查看文件时,第一列字符包含了丰富的权限信息:drwxr-xr-- 1 user1 dev 4096 Jun 1 10:00 documents↑↑↑↑↑↑↑↑↑1 23456789第1位:文件类型标识-:普通文件d:目录l:符号链接c:字符设备(如键盘、显示器)b:块设备(如磁盘)第2-10位:权限位,每3位一组2-4位:拥有者权限5-7位:所属组权限8-10位:其他用户权限权限位含义r(读权限,4):允许读取文件内容或列出目录条目w(写权限,2):允许修改文件内容或在目录中创建/删除文件x(执行权限,1):允许执行文件或进入目录-:无对应权限3.2 chmod命令:权限修改的万能工具1. 符号模式修改权限chmod [u/g/o/a][+/-/=][rwx] 文件名u:拥有者(user)g:所属组(group)o:其他用户(other)a:所有用户(all)+:添加权限-:移除权限=:设置精确权限示例:chmod u+x script.sh   # 为拥有者添加执行权限chmod g-w,o-r file.txt # 移除所属组的写权限和其他用户的读权限chmod a=rwx directory # 为所有用户设置读写执行权限2. 八进制模式修改权限将rwx转换为二进制,每3位对应一个八进制数:rwx = 111 = 7rw- = 110 = 6r-x = 101 = 5r-- = 100 = 4-wx = 011 = 3-w- = 010 = 2--x = 001 = 1--- = 000 = 0示例:chmod 755 script.sh   # 拥有者rwx,所属组r-x,其他用户r-xchmod 644 config.txt  # 拥有者rw-,所属组r--,其他用户r--chmod 700 private.sh  # 仅拥有者有rwx权限,其他用户无任何权限3. 权限修改的前提条件只有文件的拥有者或root用户可以修改文件权限目录的权限修改同样遵循此规则3.3 chown与chgrp:拥有者与所属组管理1. chown:修改文件拥有者chown 新拥有者 文件名        # 单纯修改拥有者chown 新拥有者:新所属组 文件名 # 同时修改拥有者和所属组chown -R 拥有者 目录名       # 递归修改目录及其所有内容的拥有者2. chgrp:修改文件所属组chgrp 新所属组 文件名       # 修改所属组chgrp -R 所属组 目录名      # 递归修改目录及其内容的所属组3. 权限要求执行chown和chgrp需要root权限普通用户可通过sudo提权执行(需在sudoers白名单中)四、目录权限的特殊含义4.1 目录权限的实际影响目录作为特殊的文件类型,其r/w/x权限具有不同于普通文件的含义:读权限(r)允许用户读取目录中的文件列表例如:使用ls命令查看目录内容写权限(w)允许用户在目录中创建新文件或子目录允许用户删除或重命名目录中的文件(即使文件不属于该用户)执行权限(x)允许用户进入目录(使用cd命令)允许用户访问目录中的文件(如读取或执行)4.2 权限组合的实际场景场景1:仅允许查看目录内容chmod 555 目录名  # r-x r-x r-x用户可以ls查看目录内容,但无法cd进入,也无法创建/删除文件场景2:允许团队协作目录chmod 775 目录名  # rwx rwx r-x拥有者和所属组可以读写执行(创建、修改、删除文件)其他用户可以查看和进入目录,但无法修改内容场景3:严格私有目录chmod 700 目录名  # rwx --- ---仅拥有者具有所有权限,其他用户无法访问五、默认权限与umask机制5.1 缺省权限的生成规则当创建新文件或目录时,系统会根据"起始权限"和"权限掩码(umask)"计算最终的默认权限:普通文件起始权限:666(rw-rw-rw-)目录起始权限:777(rwxrwxrwx)最终权限 = 起始权限 & (~umask),即起始权限减去umask指定的权限5.2 umask命令详解1. 查看当前umaskumask  # 输出如0002,其中第一位为特殊权限标志,后三位为权限掩码2. 设置umaskumask 0002  # 设置权限掩码(临时生效,重启后恢复)3. 权限计算示例场景:umask=0002普通文件最终权限:666 & ~0002 = 664(rw-rw-r–)目录最终权限:777 & ~0002 = 775(rwxrwxr-x)场景:umask=022普通文件最终权限:666 & ~022 = 644(rw-r–r–)目录最终权限:777 & ~022 = 755(rwxr-xr-x)5.3 umask的配置与持久化1. 临时修改(当前会话有效)umask 0002  # 修改当前shell的umask2. 永久修改(针对所有用户)vim /etc/profile  # 在文件末尾添加umask 0002source /etc/profile  # 使修改立即生效3. 针对特定用户修改vim ~/.bashrc  # 在用户配置文件中添加umask设置source ~/.bashrc  # 使修改立即生效六、权限管理最佳实践6.1 安全原则最小权限原则:只给用户分配完成任务所需的最低权限避免直接使用root:通过sudo进行精确授权定期审查权限:检查系统中是否有过度授权的用户或文件6.2 常见场景处理1. 软件安装权限安装到系统目录(如/usr/local)需要sudo权限说明:这些目录属于系统范围,安装的软件应为所有用户可用2. 团队协作目录设置创建共享组:groupadd devteam将团队成员加入组:usermod -aG devteam user1设置目录所属组:chgrp devteam shared_dir配置权限:chmod 775 shared_dir3. 安全的用户目录用户家目录应设置为700权限(rwx— —)避免其他用户访问和修改个人文件6.3 权限故障排除无法访问文件:检查是否为文件拥有者,或属于文件所属组无法执行文件:确保文件有x权限,且所在目录有x权限无法删除文件:检查文件所在目录是否有w权限sudo权限问题:确认用户是否在sudoers白名单中,可通过visudo检查配置通过深入理解Linux权限体系,系统管理员可以构建安全、灵活的访问控制机制,而普通用户也能更好地理解自己的操作权限边界,从而更安全高效地使用Linux系统。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/2302_78391795/article/details/148368911
  • [技术干货] 重启 nginx-转载
    首先确认Nginx是否已经安装,并检查它的安装位置。 执行以下命令来检查:which nginx #例如:显示/usr/local/nginx/sbin/nginx运行方法1:直接使用完整路径启动Nginx1.1、启动 Nginx,执行命令:sudo /usr/local/nginx/sbin/nginx1.2、停止(立即停止) Nginx,执行命令:sudo /usr/local/nginx/sbin/nginx -s stop1.3、停止(平滑停止) Nginx,执行命令:sudo /usr/local/nginx/sbin/nginx -s quit1.4、重启(先停再启) Nginx,执行命令:sudo /usr/local/nginx/sbin/nginx -s quitsudo /usr/local/nginx/sbin/nginx1.5、重新加载配置文件sudo /usr/local/nginx/sbin/nginx -s reload1.6、检查配置文件语法sudo /usr/local/nginx/sbin/nginx -tAI写代码bash方法2:创建systemd服务文件为了更方便地管理Nginx服务,推荐创建一个systemd服务文件。以下是具体步骤:创建服务文件: 创建一个新的服务文件/etc/systemd/system/nginx.service,并添加以下内容:[Unit]Description=A high performance web server and a reverse proxy serverAfter=network.target [Service]ExecStart=/usr/local/nginx/sbin/nginxExecReload=/usr/local/nginx/sbin/nginx -s reloadExecStop=/usr/local/nginx/sbin/nginx -s quitPrivateTmp=true [Install]WantedBy=multi-user.target重新加载systemd配置: 让systemd重新读取配置文件:sudo systemctl daemon-reload启动和启用Nginx服务: 启动Nginx服务,并设置为开机自启:sudo systemctl start nginxsudo systemctl enable nginx检查Nginx状态: 确认Nginx是否成功启动:sudo systemctl status nginx验证Nginx是否成功启动 无论选择哪种方法启动Nginx,都可以通过以下命令来验证Nginx是否正在运行:ps -ef | grep nginx或者,可以查看Nginx的错误日志以获取更多信息:tail -f /usr/local/nginx/logs/error.logAI写代码bash现在,您已经完成了Nginx的安装和启动过程。您可以通过浏览器访问服务器的IP地址来验证Nginx是否正常工作。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/Smile_Gently/article/details/143761165
  • [技术干货] Linux 系统的安全权限管理:从基础到实践
    Linux 系统的安全权限管理:从基础到实践在数字化时代,数据安全至关重要,而作为服务器领域应用广泛的 Linux 系统,其安全权限管理机制是守护系统与数据的坚固防线。深入理解并合理运用 Linux 的安全权限管理,不仅能保障系统稳定运行,还能有效防止数据泄露和恶意攻击。接下来,我们将从基础概念、核心命令以及实用安全策略等方面,全面解析 Linux 系统的安全权限管理。一、Linux 权限管理基础概念在 Linux 系统中,文件和目录都被赋予了特定的权限,这些权限决定了用户对它们的操作能力。权限管理主要围绕三个核心要素展开:用户(User)、用户组(Group)和其他用户(Others),同时涉及三种基本权限类型:读(Read,简写为r)、写(Write,简写为w)和执行(Execute,简写为x)。用户:系统中的每一个使用者都有一个唯一的用户账号,每个用户都有自己的主目录和个性化配置。例如,当创建一个新用户testuser时,系统会自动在/home目录下创建一个同名的主目录/home/testuser。用户组:为了便于管理多个用户,Linux 引入了用户组的概念。一个用户可以属于多个用户组,通过将用户添加到不同的用户组,可以批量管理用户对文件和目录的访问权限。比如,在一个开发团队中,可以创建一个名为developers的用户组,将所有开发人员添加到该组,方便对项目文件设置统一权限。其他用户:除了文件所有者和所属用户组的成员之外,系统中的其他所有用户都属于 “其他用户” 范畴。这一设置使得系统在保障文件所有者权益的同时,也能对其他用户的访问进行限制。权限的组合构成了文件和目录的访问控制体系。例如,对于一个文件,如果其权限表示为rwxr-xr–,从左到右,前三个字符rwx表示文件所有者具有读、写、执行权限;中间三个字符r-x表示文件所属用户组的成员具有读和执行权限,但没有写权限;最后三个字符r–表示其他用户仅有读权限。二、核心权限管理命令1. chmod命令:修改文件或目录权限chmod命令是 Linux 系统中用于修改文件和目录权限的核心工具,它支持两种不同的权限设定方式:字母模式和数字模式。字母模式:通过使用字母组合来指定权限的修改。例如,chmod u+x file.txt命令表示为文件file.txt的所有者添加执行权限;chmod g-w directory命令则用于移除目录directory所属用户组成员的写权限。这种方式直观易懂,适合对权限修改需求较为简单的场景。数字模式:基于权限的二进制表示,将读、写、执行权限分别对应数字 4、2、1。通过将不同权限对应的数字相加,可以得到一个三位数字来表示权限。例如,rwxr-xr–对应的数字是754(所有者:4+2+1=7;用户组:4+1=5;其他用户:4=4)。使用chmod 754 file.txt命令,即可一次性设置文件file.txt的权限为rwxr-xr–。数字模式在批量修改权限或编写脚本时更为高效。2. chown命令:更改文件或目录所有者chown命令用于更改文件或目录的所有者。例如,当需要将文件report.doc的所有者从user1变更为user2时,可以执行chown user2 report.doc命令;如果希望同时更改文件的所属用户组为group1,则可以使用chown user2:group1 report.doc命令。此外,-R选项可用于递归修改目录及其子目录下所有文件的所有者和所属用户组,在处理大型目录结构时非常实用。3. chgrp命令:修改文件或目录所属用户组chgrp命令专门用于修改文件或目录的所属用户组。例如,执行chgrp developers project_folder命令,即可将目录project_folder的所属用户组更改为developers。同样,-R选项也适用于递归修改目录下所有文件的所属用户组。三、实用安全权限管理策略1. 最小权限原则最小权限原则是 Linux 安全权限管理的核心准则之一,即只赋予用户和进程完成其任务所必需的最小权限。例如,对于一个仅用于展示静态内容的 Web 服务器,其运行的用户账户只需拥有读取网页文件的权限,而不应具备写入或执行其他文件的权限。通过严格遵循最小权限原则,可以有效降低因权限滥用或权限过大导致的安全风险,即使系统受到攻击,攻击者也难以利用过高的权限进行破坏。2. 定期审查权限随着系统的使用和用户、文件的变动,文件和目录的权限设置可能逐渐变得混乱,从而产生安全隐患。因此,定期审查系统中的文件和目录权限至关重要。可以编写脚本,使用find命令配合权限参数,查找出权限设置异常的文件。例如,find / -type f -perm /666命令将查找出系统中所有所有者和所属用户组具有写权限(权限包含w)的文件,对于这些文件,需要仔细检查其权限设置是否合理,及时进行调整。3. 使用 ACL(访问控制列表)ACL 是 Linux 系统提供的一种更精细的权限管理机制,它突破了传统的用户、用户组和其他用户的权限管理模式。通过 ACL,可以为单个用户或用户组设置特定的权限,实现对文件和目录的个性化访问控制。例如,在一个共享文件服务器中,除了设置文件的基本权限外,还可以使用setfacl -m u:user3:rwx file.txt命令,为用户user3单独赋予对文件file.txt的读、写、执行权限,而无需修改文件的基本权限设置,从而在不影响原有权限体系的基础上,实现更灵活的权限分配。4. 限制 SUID 和 SGID 权限的使用SUID(Set User ID)和 SGID(Set Group ID)是 Linux 系统中的特殊权限标志。当文件设置了 SUID 权限时,其他用户执行该文件时将临时拥有文件所有者的权限;设置了 SGID 权限的文件,执行时用户将临时拥有文件所属用户组的权限。虽然这些特殊权限在某些场景下非常有用,例如/bin/passwd文件设置了 SUID 权限,使得普通用户能够以 root 权限修改自己的密码,但如果滥用或错误使用,可能会导致严重的安全漏洞。因此,应严格限制 SUID 和 SGID 权限的使用范围,定期检查系统中设置了这些特殊权限的文件,确保其安全性和必要性。可以使用find / -type f ( -perm -4000 -o -perm -2000 ) -exec ls -l {} ;命令查找系统中设置了 SUID 或 SGID 权限的文件,并进行详细审查。
  • [技术干货] Linux 系统的用户权限管理:从基础到实战
    Linux 系统的用户权限管理:从基础到实战在 Linux 操作系统中,用户权限管理是保障系统安全、稳定运行的核心机制之一。合理的权限管理不仅能防止未经授权的访问和操作,还能确保多用户环境下数据的保密性、完整性和可用性。本文将深入探讨 Linux 用户权限管理的基本概念、核心命令以及实际应用场景,帮助你掌握这一重要技能。一、Linux 用户权限管理基础概念1.1 用户与用户组在 Linux 系统中,用户是系统资源访问和操作的主体,每个用户都有唯一的用户 ID(UID)和用户组 ID(GID)。用户分为三类:超级用户(root):UID 为 0,拥有对系统所有资源的绝对控制权,可以执行任何操作,如安装软件、修改系统配置、管理其他用户等。普通用户:UID 范围通常从 1000 开始,只能访问和操作属于自己的文件和被授权的系统资源,以保证系统安全。系统用户:UID 范围一般在 1 - 999 之间,主要用于运行系统服务,如www-data用于 Web 服务器,mysql用于数据库服务等,这类用户通常不允许登录系统。用户组是将具有相同权限需求的用户集合在一起的逻辑概念,一个用户可以属于多个用户组。通过将用户添加到不同的用户组,可以批量分配权限,简化管理。1.2 权限分类Linux 系统中的文件和目录权限分为三种基本类型,每种类型对应不同的用户角色:所有者权限(Owner):文件或目录的创建者,拥有对其的最高控制权,可以设置读(r)、写(w)、执行(x)权限。所属组权限(Group):文件或目录所属用户组内的成员所具有的权限,同样包含读、写、执行三种权限。其他用户权限(Others):除所有者和所属组用户之外的其他所有用户所具有的权限。这三种权限组合起来,可以用数字或符号表示。例如,rwxr-xr–表示所有者具有读、写、执行权限,所属组具有读和执行权限,其他用户只有读权限;用数字表示则为754(rwx = 4+2+1 = 7,r-x = 4+0+1 = 5,r-- = 4+0+0 = 4)。二、Linux 用户权限管理核心命令2.1 用户管理命令useradd:用于创建新用户。例如,useradd -m -s /bin/bash newuser命令会创建一个名为newuser的新用户,-m选项表示为用户创建主目录,-s选项指定用户的默认登录 Shell 为/bin/bash。userdel:用于删除用户。userdel -r olduser命令会删除名为olduser的用户及其主目录和邮件池(-r选项表示递归删除相关文件和目录)。usermod:用于修改用户属性。如usermod -aG sudo newuser命令将newuser添加到sudo用户组,使其具备使用sudo命令获取临时管理员权限的能力。2.2 用户组管理命令groupadd:创建新用户组,如groupadd developers创建一个名为developers的用户组。groupdel:删除用户组,groupdel developers可删除developers用户组(需确保组内没有用户)。gpasswd:管理用户组密码和成员。gpasswd -a user1 developers将user1添加到developers用户组,gpasswd -d user1 developers则将其从该组移除。2.3 文件权限管理命令chmod:用于修改文件或目录的权限。可以使用符号模式或数字模式,如chmod u+x file.txt为文件file.txt的所有者添加执行权限,chmod 760 dir将目录dir的权限设置为所有者可读、写、执行,所属组可读、写,其他用户无权限。chown:更改文件或目录的所有者和所属组。chown user1:group1 file.txt将文件file.txt的所有者改为user1,所属组改为group1。chgrp:仅更改文件或目录的所属组,chgrp developers project将project目录的所属组改为developers。三、实际应用场景3.1 多用户协作项目在软件开发团队中,多个开发人员需要共同访问和修改项目文件。可以创建一个developers用户组,将所有开发人员添加到该组,然后将项目目录的所属组设置为developers,并赋予组内成员适当的读写权限。例如:groupadd developers usermod -aG developers user1 usermod -aG developers user2 chown -R root:developers project chmod -R g+rw project这样,user1和user2就可以协作开发项目,同时保证其他用户无法随意访问和修改项目文件。3.2 服务器安全设置为了提高服务器的安全性,通常不建议直接使用root用户登录,而是创建一个普通用户,并赋予其sudo权限。首先创建用户:useradd -m -s /bin/bash adminuser然后将用户添加到sudo用户组:usermod -aG sudo adminuser之后,管理员可以使用adminuser登录服务器,通过sudo命令执行需要管理员权限的操作,如安装软件、修改系统配置等。同时,可以通过配置sudoers文件(使用visudo命令编辑),进一步细化用户的权限,只允许其执行特定的命令,降低误操作和恶意攻击的风险。四、总结与注意事项Linux 用户权限管理是一个复杂但至关重要的系统功能。通过合理管理用户、用户组和文件权限,可以有效保障系统安全和数据隐私。在实际操作中,需要注意以下几点:谨慎使用 root 权限:避免频繁使用root用户进行日常操作,尽量通过sudo以普通用户身份执行必要的管理任务。定期检查权限设置:定期检查系统中文件和目录的权限,确保没有过度开放的权限,防止潜在的安全风险。遵循最小权限原则:只给用户和用户组分配完成任务所需的最小权限,避免权限滥用。掌握 Linux 用户权限管理技能,不仅能提升系统管理效率,还能为系统安全筑起坚实的防线。希望本文的内容能帮助你更好地理解和应用 Linux 用户权限管理机制。
  • 一文读懂通信系统等级备案:合规运营与安全防护的必修课
    在数字化浪潮席卷全球的今天,通信系统作为信息传递的 “神经中枢”,其安全性与合规性愈发重要。通信系统等级备案,正是保障通信系统安全稳定运行、确保企业合法合规经营的关键环节。今天,就让我们深入探讨通信系统等级备案的方方面面。一、通信系统等级备案是什么?通信系统等级备案,全称为通信网络安全防护等级保护备案,是依据国家相关法律法规和技术标准,对通信系统按照其在国家安全、经济建设、社会生活中的重要程度,以及遭到破坏后对国家安全、社会秩序、公共利益以及公民、法人和其他组织的合法权益的危害程度等因素,划分为不同的安全保护等级,并进行相应的备案管理工作 。简单来说,就是给通信系统划分安全 “等级”,并向相关部门报备,以便采取针对性的安全防护措施。目前,我国通信系统安全保护等级分为五级,从第一级(自主保护级)到第五级(专控保护级),安全保护要求逐级升高。第一级适用于一般的小型通信系统,对安全要求相对较低;而第五级则主要针对涉及国家安全等核心领域的关键通信系统,需要极为严格的安全防护。二、为什么通信系统等级备案如此重要?(一)法律合规要求根据《网络安全法》《通信网络安全防护管理办法》等法律法规,通信系统运营者有义务对通信系统进行等级保护备案。未按规定进行备案的,将面临责令整改、罚款,甚至暂停相关业务等处罚。对于企业而言,合规是生存和发展的基础,忽视等级备案可能会给企业带来巨大的法律风险和经济损失。(二)保障系统安全通过等级备案,运营者能够清晰地认识到自身通信系统的安全等级和安全需求,从而按照相应等级的防护标准,有针对性地加强安全技术措施和管理措施。这有助于及时发现和修复系统漏洞,防范网络攻击、数据泄露等安全威胁,保障通信系统的稳定运行和数据安全。(三)提升企业信誉完成通信系统等级备案,表明企业具备良好的网络安全管理能力和合规意识,能够为用户提供更安全可靠的服务。这在市场竞争中是一张重要的 “信任名片”,有助于提升企业的品牌形象和市场竞争力,赢得用户和合作伙伴的信任。三、通信系统等级备案的流程详解(一)系统定级运营者首先需要组织专业人员或委托专业机构,依据相关标准对通信系统进行定级。在定级过程中,要充分考虑系统的功能、服务对象、业务重要性等因素,科学合理地确定系统的安全保护等级。定级完成后,需形成详细的定级报告。(二)备案材料准备根据相关要求,准备备案所需的材料,通常包括:《通信网络安全防护等级保护备案表》,详细填写通信系统的基本信息、安全保护等级等内容。定级报告,说明系统定级的依据、过程和结果。系统拓扑结构及说明,展示通信系统的网络架构和组成部分。其他相关材料,如系统安全管理制度、应急预案等。(三)提交备案将准备好的备案材料提交至当地通信管理局或相关主管部门。提交方式可以是现场提交或通过线上备案系统提交。提交后,等待主管部门对备案材料进行审核。(四)审核与整改主管部门在收到备案材料后,会对材料的完整性、准确性以及系统定级的合理性进行审核。如果审核不通过,运营者需要根据主管部门的反馈意见,对备案材料或系统进行整改,然后重新提交审核。审核通过后,主管部门将发放备案证明,标志着通信系统等级备案工作完成。四、通信系统等级备案常见问题与解决方案(一)定级不准确部分企业由于对定级标准理解不深入,导致通信系统定级过高或过低。定级过高会增加不必要的安全投入成本,而定级过低则无法有效保障系统安全。解决方案是加强对相关标准的学习,必要时聘请专业的安全评估机构协助定级,确保定级结果科学合理。(二)备案材料不规范备案材料填写不完整、格式不正确、内容不准确等问题较为常见。这就要求运营者在准备材料时,仔细研读备案要求,严格按照规范填写和整理材料。可以提前向主管部门咨询,获取准确的材料模板和填写指南。(三)后续安全防护不到位完成备案并不意味着一劳永逸,后续还需要按照相应等级的安全防护要求,持续加强系统的安全管理和技术防护。部分企业存在重备案、轻防护的问题,这将使备案失去实际意义。企业应建立完善的网络安全管理制度,定期进行安全检查和风险评估,及时更新安全防护措施,确保通信系统始终处于安全状态。通信系统等级备案是保障通信系统安全、企业合规运营的重要举措。无论是大型通信运营商,还是拥有内部通信系统的企业,都应充分认识到等级备案的重要性,严格按照规定流程完成备案工作,并持续做好后续的安全防护。只有这样,才能在数字化时代,为通信系统的稳定运行和企业的健康发展筑牢安全防线。
  • Linux 时钟同步原理分析与实践指南:精准时间背后的技术奥秘
    在分布式系统和网络环境中,Linux 系统的时钟同步至关重要,它影响着日志分析、分布式事务等多个关键环节。下面这篇博客将从原理入手,结合实际操作,为你全面讲解 Linux 时钟同步。Linux 时钟同步原理分析与实践指南:精准时间背后的技术奥秘在数字化时代,时间的精准性对于计算机系统至关重要。无论是分布式系统中的数据一致性保障,还是网络服务的日志追踪,都依赖于准确的时钟。对于 Linux 系统而言,时钟同步是确保系统稳定运行、服务可靠提供的基础功能。本文将深入剖析 Linux 时钟同步的原理,并通过详细的实践步骤,带你掌握这一核心技术。一、Linux 时钟同步的重要性在企业级应用场景中,不准确的时钟可能引发严重问题。例如,在分布式数据库的主从复制中,时间不一致会导致数据同步错误;在微服务架构里,错误的时间戳会使服务调用链追踪失去意义;在安全审计领域,混乱的时间记录将无法准确还原操作顺序。因此,实现 Linux 系统的精准时钟同步,是保障系统正常运行的必要条件。二、Linux 时钟系统基础概念2.1 硬件时钟与系统时钟Linux 系统存在两种时钟概念:硬件时钟(RTC,Real - Time Clock):由计算机主板上的专用芯片维持,即使系统断电,也能依靠主板电池持续计时,是系统时间的物理基础。系统时钟:Linux 内核在系统运行时维护的时钟,其时间来源初始时通常是硬件时钟,在系统运行过程中,可通过网络时间协议等方式进行更新和校准 。2.2 时间标准全球通用的时间标准主要有:UTC(协调世界时):基于原子钟的高精度时间标准,同时结合天文观测结果,通过闰秒调整来保持与地球自转时间的同步,是国际标准时间的基础。NTP 时间:网络时间协议(Network Time Protocol)所使用的时间标准,常用于计算机网络中的时钟同步,以 UTC 为基础进行时间传递和校准。三、Linux 时钟同步原理3.1 网络时间协议(NTP)NTP 是 Linux 系统实现时钟同步的常用协议,其工作原理基于客户端 - 服务器模型:时间请求与响应:客户端向 NTP 服务器发送时间同步请求,请求报文中包含客户端发送请求的时间戳(T1)。服务器接收到请求后,记录接收时间(T2),并在处理请求后,记录发送响应的时间(T3),然后将 T1、T2、T3 以及服务器自身的当前时间(T4)封装在响应报文中返回给客户端。时间计算:客户端收到响应后,根据公式计算与服务器的时间偏移量和网络延迟。时间偏移量 = [(T2 - T1) + (T3 - T4)] / 2,网络延迟 = (T4 - T1) - (T3 - T2)。通过计算出的时间偏移量,客户端调整自身的系统时钟,实现与服务器的时间同步 。层级体系(Stratum):NTP 采用层级体系来组织服务器,Stratum 0 为最顶层,通常是原子钟、GPS 接收器等高精度时间源;Stratum 1 服务器直接与 Stratum 0 设备相连,作为一级时间服务器;Stratum 2 服务器从 Stratum 1 服务器获取时间,依此类推。层级越低,时间精度越高,客户端通常选择较低层级的 NTP 服务器进行同步 。3.2 其他时钟同步机制除了 NTP,还有一些其他的时钟同步技术:PTP(精确时间协议,Precision Time Protocol):适用于对时间精度要求极高的场景,如工业自动化、金融交易系统等。PTP 不仅依赖软件,还需要硬件支持,通过专用的 PTP 网卡和支持 PTP 协议的交换机,能够实现亚微秒级的时间同步精度 。Chrony:是 NTP 的一种实现方式,相比传统 NTP,Chrony 在时钟同步的快速性和准确性上有显著提升,尤其在网络条件不稳定的情况下,能更好地适应时间变化,减少时间同步的误差和延迟 。四、Linux 时钟同步实践4.1 使用 NTP 进行时钟同步(以 Ubuntu 系统为例)安装 NTP 服务:打开终端,输入命令sudo apt - get install ntp,按照提示完成安装。配置 NTP 服务器:NTP 服务安装完成后,其配置文件位于/etc/ntp.conf。默认情况下,Ubuntu 系统会自动配置一些公共的 NTP 服务器。如果需要自定义服务器,可以在配置文件中添加或修改。例如,添加阿里云的 NTP 服务器。启动和重启 NTP 服务:安装和配置完成后,使用命令sudo systemctl start ntp启动 NTP 服务;如果之前已经启动过 NTP 服务,在修改配置后,可使用命令sudo systemctl restart ntp重启服务,使配置生效。验证时钟同步状态:使用命令ntpq -p查看 NTP 服务器的连接状态和同步信息。命令执行后,会列出 NTP 服务器列表,包括服务器的地址、层级、延迟、偏移量等信息。如果reach列的值不为 0,且offset列的值在可接受范围内(通常较小),则表示时钟同步正常 。4.2 使用 Chrony 进行时钟同步(以 CentOS 系统为例)安装 Chrony:在 CentOS 系统中,使用命令sudo yum install chrony安装 Chrony 服务。启动和设置开机自启:安装和配置完成后,使用命令sudo systemctl start chronyd启动 Chrony 服务;使用命令sudo systemctl enable chronyd设置 Chrony 服务开机自启,确保系统每次启动时都能自动进行时钟同步 。查看同步状态:使用命令chronyc sources -v查看 Chrony 与 NTP 服务器的同步状态,命令执行后会显示服务器的相关信息以及同步情况;使用命令chronyc tracking查看当前系统时钟的详细同步信息,包括时间源、偏移量、误差等 。4.3 手动同步时钟在某些特殊情况下,如无法连接到网络时间服务器,或者需要紧急校准时间时,可以手动同步时钟:设置系统时间:使用命令sudo date -s "YYYY - MM - DD HH:MM:SS"手动设置系统时间,将YYYY - MM - DD HH:MM:SS替换为实际的日期和时间 。将系统时间写入硬件时钟:设置好系统时间后,使用命令sudo hwclock -w将系统时间写入硬件时钟,确保下次系统启动时,硬件时钟的时间是准确的 。五、时钟同步常见问题与解决方法5.1 无法连接到 NTP 服务器原因:可能是网络连接问题、防火墙阻止了 NTP 服务的端口(UDP 123 端口)、NTP 服务器地址配置错误等。解决方法:检查网络连接是否正常;如果是防火墙问题,可使用命令sudo ufw allow 123/udp开放 UDP 123 端口;检查 NTP 服务器地址配置,确保地址正确且可用,可以尝试更换其他 NTP 服务器进行同步 。5.2 时钟同步后时间仍然不准确原因:NTP 服务器自身时间不准确、网络延迟较大导致同步误差、系统时钟存在较大偏差等。解决方法:更换更可靠的 NTP 服务器;检查网络环境,减少网络延迟;如果系统时钟偏差较大,可以尝试多次进行时钟同步,或者手动设置一个较准确的初始时间,再进行同步 。5.3 硬件时钟时间错误原因:主板电池电量不足、硬件时钟芯片故障等。解决方法:更换主板电池;如果怀疑硬件时钟芯片故障,可能需要专业人员进行检修或更换硬件 。六、总结Linux 时钟同步是一项看似基础却又至关重要的技术,深入理解其原理并熟练掌握实践方法,能够有效保障系统的正常运行和服务的可靠提供。无论是通过 NTP、Chrony 等协议进行网络时间同步,还是在特殊情况下手动同步时钟,都需要我们根据实际需求和场景进行选择和操作。同时,对于时钟同步过程中可能出现的问题,要能够准确分析原因并采取有效的解决措施。通过不断学习和实践,我们可以更好地驾驭 Linux 系统的时钟同步,为数字化工作和生活提供坚实的时间保障。如果你在实际操作中遇到其他问题,或者想了解更多关于 Linux 系统优化的内容,欢迎在评论区留言交流!以上博客涵盖了 Linux 时钟同步多方面内容。若你觉得某些部分需要补充案例、调整深度,或有其他修改需求,随时和我说。
  • [技术干货] Linux 时钟同步原理分析与实践指南:从 NTP 到 PTP
    Linux 时钟同步原理分析与实践指南:从 NTP 到 PTP在分布式系统中,时钟同步是保障系统正常运行的基石。从数据库主从复制到微服务调用链追踪,从金融交易记录到安全审计,准确的时间戳是所有分布式应用的生命线。本文将深入探讨 Linux 系统中时钟同步的核心原理、主流技术方案及实战配置方法。一、时钟同步的核心价值与挑战1.1 为什么需要时钟同步?分布式事务一致性:确保跨节点事务的时间顺序正确性日志关联分析:统一时间戳便于故障排查和日志聚合安全审计:准确的时间戳是安全事件追溯的基础协议运行依赖:如 MySQL 主从复制、Kafka 消息顺序等1.2 分布式系统中的时钟挑战物理时钟差异:不同服务器的硬件时钟存在固有漂移网络延迟不确定性:NTP 协议受网络抖动影响闰秒处理:UTC 与 TAI 时间的差异调整可能导致系统异常安全威胁:时钟被攻击可能导致数据混乱或安全漏洞二、Linux 时钟同步的基本原理2.1 硬件时钟与系统时钟硬件时钟(RTC):主板上的实时时钟,断电后由电池供电系统时钟(System Time):Linux 内核维护的时钟,启动时从 RTC 同步关系:系统时钟通过 NTP/PTP 等协议定期校准,硬件时钟可通过hwclock命令与系统时钟同步2.2 时间标准体系UTC(协调世界时):全球通用的时间标准,基于原子钟并定期调整闰秒TAI(国际原子时):连续计时,不调整闰秒,与 UTC 存在固定偏差(当前为 37 秒)GPS 时间:基于 GPS 卫星的时间系统,与 TAI 同步但无闰秒调整2.3 时钟同步算法基础SNTP(简单 NTP):单向时间同步,精度约 100msNTP(网络时间协议):双向时间同步,通过往返延迟计算,精度可达 10msPTP(精确时间协议):基于硬件时钟同步,精度可达亚微秒级(需专用网卡支持)三、NTP 协议详解与实战配置3.1 NTP 协议工作原理NTP 通过交换时间戳报文,计算客户端与服务器之间的时间偏移和网络延迟:图片代码sequenceDiagram Client->>Server: T1时刻发送请求 Server->>Client: T2时刻接收请求,T3时刻发送响应 Client->>Client: T4时刻接收响应 Note right of Client: 计算偏移量θ = [(T2-T1)+(T3-T4)]/2 Note right of Client: 计算往返延迟δ = (T4-T1)-(T3-T2) ServerClientServerClient计算偏移量θ = [(T2-T1)+(T3-T4)]/2计算往返延迟δ = (T4-T1)-(T3-T2)T1时刻发送请求T2时刻接收请求,T3时刻发送响应T4时刻接收响应3.2 NTP 服务器层级(Stratum)Stratum 0:原子钟、GPS 接收器等物理时钟源Stratum 1:直接连接 Stratum 0 的 NTP 服务器Stratum 2:从 Stratum 1 同步的 NTP 服务器依此类推:每增加一级,精度降低约 10%3.3 Ubuntu/Debian 系统 NTP 配置实战安装 NTP 服务bashsudo apt-get install ntp配置 NTP 服务器(/etc/ntp.conf)ini# 上游NTP服务器(中国地区推荐) server ntp.aliyun.com iburst server ntp.tencent.com iburst server cn.pool.ntp.org iburst # 禁止外部访问本服务器的NTP服务 restrict default kod nomodify notrap nopeer noquery restrict 127.0.0.1 restrict ::1 启动并验证服务bashsudo systemctl start ntp sudo systemctl enable ntp ntpq -p # 查看NTP服务器同步状态 手动同步时钟(紧急情况)bashsudo timedatectl set-ntp false # 临时禁用NTP服务 sudo date -s "2023-06-30 12:00:00" # 手动设置时间 sudo hwclock -w # 将系统时间写入硬件时钟 sudo timedatectl set-ntp true # 重新启用NTP服务 四、PTP 协议详解与高精度同步方案4.1 PTP 与 NTP 的核心差异特性NTPPTP精度毫秒级(10ms-100ms)亚微秒级(<1μs)实现方式纯软件实现需要硬件支持(PTP 网卡)网络要求标准以太网支持 IEEE 1588v2 协议的网络适用场景普通服务器时钟同步工业控制、金融交易等高精度场景4.2 PTP 协议工作模式E2E(端到端)模式:只在报文的发送和接收端记录时间戳P2P(点对点)模式:在网络路径中的每个交换机都记录时间戳,补偿网络延迟4.3 Linux 系统 PTP 配置实战确认网卡支持 PTPbashethtool -T eth0 # 查看网卡时间戳能力 安装 PTP 服务(以 LinuxPTP 为例)bashsudo apt-get install linuxptp配置 PTP 主时钟(Grandmaster)ini# /etc/linuxptp/ptp4l.conf [global] logging_level 7 uds_transport 1 time_stamping hardware # 使用硬件时间戳 [eth0] # 替换为实际网卡名 delay_mechanism E2E 配置 PTP 从时钟ini# /etc/linuxptp/ptp4l.conf [global] logging_level 7 uds_transport 1 time_stamping hardware [eth0] delay_mechanism E2E slaveOnly 1 # 设置为从时钟模式启动服务并验证同步bashsudo systemctl start ptp4l # 启动PTP服务 sudo phc2sys -s eth0 -c system # 将PTP时钟同步到系统时钟 watch -n 1 "ptp4l -c eth0 -m" # 实时监控同步状态 五、时钟同步的监控与故障排查5.1 常用监控工具ntpq:NTP 服务状态查询工具bashntpq -p # 查看NTP服务器连接状态 ntpq -c rv # 查看详细同步信息 chronyc:Chrony 服务监控工具bashchronyc sources # 查看时间源状态 chronyc tracking # 查看时钟追踪信息 timedatectl:系统时间管理工具bashtimedatectl status # 查看当前时间同步状态 5.2 常见故障排查问题现象可能原因解决方法NTP 无法同步防火墙阻止 UDP 123 端口开放防火墙规则:sudo ufw allow 123/udp时钟偏差持续增大NTP 服务器选择不当更换更可靠的 NTP 服务器(如阿里云、腾讯云 NTP)PTP 同步失败网卡不支持硬件时间戳更换支持 IEEE 1588v2 的网卡闰秒调整导致服务异常应用程序未正确处理闰秒升级应用或配置 NTP 服务忽略闰秒:tinker panic 0六、时钟同步的安全考量6.1 时钟攻击类型拒绝服务攻击:通过发送虚假 NTP 报文扰乱时钟同步重放攻击:利用过时的时间戳进行恶意操作时间偏移攻击:通过调整时钟影响事务顺序6.2 安全增强措施启用 NTP 认证:在ntp.conf中配置密钥认证initrustedkey 1 2 3 key 1 md5 your-secret-key使用 Chrony 替代传统 NTP:Chrony 对网络抖动更具弹性部署本地 NTP 服务器:减少对公共 NTP 服务器的依赖监控时钟异常:设置阈值监控时钟偏移,异常时触发告警七、总结与最佳实践按需选择同步方案:普通应用:使用 NTP(如 chrony)即可满足需求高精度场景:部署 PTP 并使用专用网卡混合方案:NTP 作为基础同步,PTP 用于关键节点配置建议:优先选择地理位置近的 NTP 服务器至少配置 3 个不同层级的 NTP 服务器定期检查硬件时钟电池状态监控与应急:建立时钟偏移监控系统(阈值建议:±50ms)制定时钟异常应急预案,包括手动同步流程
  • [技术干货] 永不休眠:Linux 守护进程的工作原理-转载
    前言在 Linux 系统中,守护进程(Daemon)是指那些在后台运行的进程,通常不与用户直接交互,而是提供某种服务或者完成系统任务。守护进程通常在系统启动时启动,并在系统运行时持续存在。进程信息字段含义字段    含义    用途    示例PPID    父进程 ID    表示当前进程的父进程的进程 ID。帮助追踪进程的父子关系。    23449PID    进程 ID    唯一标识当前进程。通过 PID 可以管理进程。    24284PGID    进程组 ID    标识当前进程所在的进程组。用于管理相关进程。    24284SID    会话 ID    标识当前进程所属的会话 ID。会话是共享同一个控制终端的进程集合。    23449TTY    终端类型    指当前进程所使用的终端设备。    pts/0TPGID    控制终端的进程组 ID    标识该进程所属的控制终端的进程组。    24284STAT    进程状态    表示进程当前的状态。常见状态包括休眠、运行、停止等。    S+UID    用户 ID    表示当前运行该进程的用户的标识符。    1000TIME    进程占用的 CPU 时间    显示该进程使用的 CPU 时间,格式为“分钟:秒”。    0:00COMMAND    执行的命令    显示当前进程正在执行的命令或程序。    sleep 100进程组ID(PGID)PGID(进程组 ID) 表示进程所在的进程组的标识符。在该输出中,所有进程的 PGID 都是 25091,说明这些进程都属于同一个进程组。这个进程组的 leader(进程组长) 是 PID 25091(它的 PGID 值是它自己的 PID),也就是说,这个进程(PID 25091)是该进程组的领导者。该进程组中的其他进程(例如 PID 25092、25093)都是由该进程创建的,它们与进程组共享同一个 PGID。为什么 PGID 相同?进程组是一个将多个相关进程组织在一起的机制。在这个例子中,sleep 100 进程的多个实例(PID 25091、25092、25093)都属于同一个进程组,它们的 PGID 是相同的。这种设计允许操作系统同时管理多个进程,比如向整个进程组发送信号,进行进程组控制等。会话ID(SID)在这里面我们创建了三个会话,SID 分别为 22449、22403、25410分别控制着不同的终端( TTY)在此会话中我们执行观察进程 sleep 的 SID = 24003:所有显示的 sleep 进程的 SID 都是 24003。这表明所有这些 sleep 进程属于同一个会话,即它们共享相同的会话 ID。SID 表示这些进程是同一个会话中的进程,会话中的所有进程都具有相同的 SID。bash : 会话的领导者:会话的 SID 通常等于会话的 leader(会话领导进程)的 PID。因此,SID = 24003 表明会话中的领导进程的 PID 是 24003。这个进程的 PID 会作为会话的 SID。这些 sleep 进程的 SID 为 24003,表明它们是由 PID = 24003 启动的进程所创建,并且它们共享该会话。前后台进程定义前台进程 是那些直接与用户交互并占用当前终端的进程,通常它们会接收用户输入并显示输出。#include <iostream>                                                                     #include <unistd.h>        using namespace std;        int main ()    {        while(1)        {            cout << "hello proc "<<endl;            sleep(1);        }        return 0;    }执行代码在前台进程,执行指令(./文件名):后台进程 则是在后台运行的进程,它们不直接与用户交互,不占用终端,通常用于执行长时间运行的任务,如守护进程或定时任务。如果在后台进程的执行的指令就是:./文件名 &后台进程的特点不占用终端:后台进程不会占用当前的控制终端(即用户的输入输出设备)。当你将一个进程放入后台运行时,终端仍然可以用来执行其他命令。不与用户交互:后台进程不直接与用户交互,因此它不会阻塞终端的使用。例如,你可以在后台运行一个长时间的下载任务,而继续在前台执行其他任务(如编辑文件、查看文件等)。异步执行:后台进程通常是异步执行的,即它们独立于当前正在运行的进程执行,不会干扰前台进程的执行前后台进程的操作jobs显示后台作业当前证明有11个任务在同时跑。fg将后台作业带回前台fg -进程编号分析:后台运行程序:执行了 ./a.out &,该命令将程序 a.out 在后台运行,并返回了进程号 [1] 27998,表示后台程序正在运行。查看输出:输入了 hello proc,终端多次显示了这个字符串,可能是 a.out 程序的输出内容。调到前台:使用 fg 1 将后台运行的程序(作业号 1)调到前台,使其开始在前台运行。此时可以看到程序输出持续显示。终止程序:按下 CTRL + C(中断信号),终止了在前台运行的程序。bg将后台作业带回前台bg -进程编号分析:./a.out:执行这个命令来运行已编译的程序 a.out。程序打印了三次 hello proc 到终端。^Z:这是一个键盘快捷键,用来暂停(停止)正在运行的程序。程序被挂起,并显示消息 [1]+ Stopped,表示该进程已暂停。bg 1:bg 命令用于将停止的进程(此处为作业号 1)恢复到后台继续运行。这样程序就可以继续执行,而不会占用终端。./a.out &:程序现在在后台运行,输出继续显示 hello proc。守护进程守护进程(Daemon)是计算机中在后台运行的一个长期存在的进程,通常在操作系统启动时自动启动,并在系统关闭时停止。它不与用户直接交互,而是负责执行一些后台任务,如定时任务、系统监控、服务提供等。守护进程的特点后台运行:守护进程不与终端直接交互,它们在后台运行,并且不会因用户登出而终止。、自启动和长期运行:大多数守护进程在系统启动时自动启动,并且通常会一直运行直到系统关闭或守护进程被手动停止。与终端分离:守护进程通常会与终端或控制台分离,这意味着它们不依赖于任何终端会话,甚至在用户退出登录后也会继续运行。编写守护进程#pragma once  // 防止该头文件被多次包含#include <iostream>      // 引入输入输出流库#include <unistd.h>      // 引入Unix标准函数库(比如fork, setsid等)#include <string>        // 引入C++标准字符串库#include <signal.h>      // 引入信号处理库(signal相关函数)#include <sys/types.h>   // 包含系统数据类型(pid_t等)#include <sys/stat.h>    // 引入文件状态和权限库#include <fcntl.h>       // 引入文件控制库const std::string nullfile = "/dev/null";  // 定义一个常量 nullfile,表示 Unix 系统中的空设备文件 /dev/nullvoid daemon(const std::string chdir = ""){    // 忽略一些常见的信号    signal(SIGCHLD, SIG_IGN);  // 忽略子进程结束信号(不需要等待子进程)    signal(SIGPIPE, SIG_IGN);  // 忽略管道破裂信号    signal(SIGSTOP, SIG_IGN);  // 忽略停止信号(通常用户发送的 Ctrl+Z)    // 将当前进程变为独立会话的领导者    if (fork() > 0)    {        // 父进程退出,子进程继续        exit(1);    }    setsid();  // 创建新的会话,脱离终端,成为会话领导者    // 如果传入了工作目录路径,尝试更改目录权限    if (!chdir.empty())        chmod(chdir.c_str(), 0777);  // chmod 需要传递权限值参数,这里假设为 0777    // 打开 /dev/null 设备文件,以只读方式打开    int fd = open(nullfile.c_str(), O_RDONLY);    if (fd > 0)    {        // 将标准输入、输出和错误输出重定向到 /dev/null        dup2(0, fd);  // 将标准输入(fd 0)重定向到 /dev/null        dup2(1, fd);  // 将标准输出(fd 1)重定向到 /dev/null        dup2(2, fd);  // 将标准错误输出(fd 2)重定向到 /dev/null        close(fd);    // 关闭文件描述符    }}忽略异常信号:守护进程通常不会干扰终端信号,因此忽略了与子进程、管道破裂和停止信号相关的信号。脱离终端:通过 fork() 和 setsid() 创建一个新的会话,使得守护进程不再受控制终端影响。修改工作目录:尝试修改工作目录(但代码存在错误,应改为 chdir())。重定向输入输出:将标准输入、输出和错误输出重定向到 /dev/null,避免进程与终端交互。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/Cayyyy/article/details/148642085
  • [技术干货] 【Linux我做主】进度条小程序深度解析-转载
    前言​ 在Linux系统编程中,控制台交互的视觉反馈是提升用户体验的重要环节。进度条作为经典的人机交互组件,在软件安装、文件传输、数据处理等场景中具有广泛应用价值。本文将以Linux环境下C语言实现的进度条程序为切入点,深入探讨控制台输出控制、缓冲区机制、函数指针应用等核心技术。通过三个版本迭代的代码解析(基础版/V1、模拟多任务版/V2),读者将掌握从原理到实践的完整知识链路。前置知识回车换行(CR/LF)的深度解析在C语言中,我们使用\n来表示换行,这其实是C语言帮我们做了处理。实际上,回车和换行其实是两个动作。C语言中用\n来表示回车和换行。以上图片深入阐述了回车和换行概念以及和区别。\r:回车,光标回到当前行的最开始。C语言中用\r来表示仅回车。\n:换行,光标垂直向下移动一行,叫做换行。历史渊源与技术规范ASCII规范定义:CR(Carriage Return,\r,ASCII 13)将光标移动到行首LF(Line Feed,\n,ASCII 10)使光标下移一行Windows系统采用CRLF组合实现新行操作Linux/Unix系统使用LF单独完成换行在进度条/倒计时中的应用printf("%-3d\r", cnt);  // 关键代码示例1此代码实现:使用%-3d保证3字符宽度左对齐3表示该值位宽为3,C语言默认为右对齐,用-来表示左对齐。\r使每次输出回到行首配合fflush(stdout)强制刷新缓冲区实现原地更新的数字倒计时效果缓冲区机制的全面剖析缓冲区引入先看如下两个例子:有换行符\n时显示器直接刷新无换行符时,像是先执行了sleep再执行printf经分析得知:C语言中一定是按顺序执行代码的,因此一定是printf先执行,再执行sleep。那么,在sleep期间,printf函数一定已经执行完了。那么,sleep期间,hello wolrd在哪里?综上,hello wolrd一定是被保存起来了!!!保存hello wolrd,必然 需要一块内存空间,这块内存空间被称为缓冲区。缓冲区就是由C语言维护的一段内存。C程序运行时,默认会帮助我们打开三个输入输出流stdin:标准输入stdout:标准输出(默认是显示器)stderr:标准错误C语言的默认行为是在程序退出时,再刷新缓冲区。printf打印消息,是向stdout输入,消息暂存在了stdout中,当我们不想让消息暂存在缓冲区中,而是想直接刷新stdout的内容到显示器时,可以使用fflush刷新,默认stdout在程序结束时刷新,使用fflush可以强制进行刷新输入输出流。以下:此时printf("hello world")没有\n使用fflush(stdout)强制将缓冲区中的数据刷新到显示器上通过以上两个例子,我们已经对缓冲区有了一个大概的理解了。缓冲类型对比缓冲类型 特征 典型应用场景全缓冲 缓冲区满时刷新 文件操作行缓冲 遇到换行符或缓冲区满时刷新 终端输出(默认)无缓冲 立即输出 标准错误流stderr进度条开发中的关键控制手动刷新机制:fflush(stdout);  // 强制立即输出缓冲区内容1进度条实现以小见大——倒计时倒计时最终效果演示代码如下:void test() {    //实现一个倒计时    int cnt = 100;    while (cnt >= 0) {        // printf("%-2d\r", cnt);//使用\r回车会导致三位数只刷新了两位数        printf("%-3d\r", cnt);  // %3d\r 可以实现在行的开头更新数字  -相当于反转  确保是左对齐        fflush(stdout);        --cnt;        sleep(1);    }    printf("\n");}int main() {    test();    return 0;}当前设置倒计时从100开始关于printf中的参数%-3d\r的解释%d的作用:表示输出数字cnt,用于显示倒计时3的作用:用于控制输出显示位宽为3,倒计时的数字是几位,位宽就设置为几。-的作用:设置位宽后,C程序默认为右对齐,我们想让数字在当前行的最左侧显示,要用-实现左对齐。\r的作用:用于实现仅回车,回到当前行的开始,覆盖打印实现倒计时的效果。使用fflush(stdout)将缓冲区内的数据立即刷新出来sleep(1)每隔一秒循环一次错误演示位宽不够带来的影响位宽小于数字的位数时,会出现数字残余的情况。由于显示器是字符设备,只会一个一个打印字符,123实际上是1 2 3三个字符连在一起表示的以下是从10开始计数的错误例子正确设置位宽即可解决。设置位宽后不反转带来的影响不用-进行反转会导致数字不靠左显示对于倒计时来说影响甚微,但靠右显示的话,会导致进度条从右向左加载!不使用\r回车带来的影响不使用\r会导致数字接连不断的出现,不符合倒计时的效果。总结回顾倒计时printf中的格式化控制参数缺一不可关于printf中的参数%-3d\r的理解%d表示输出数字cnt,用于显示倒计时3用于控制输出显示位宽为3,倒计时的数字是几位,位宽就设置为几。设置位宽后,C程序默认为右对齐,我们想让数字在当前行的最左侧显示,要用-实现左对齐。\r用于实现仅回车,回到当前行的开始,覆盖打印实现倒计时的效果。使用fflush(stdout)将缓冲区内的数据立即刷新出来进度条架构设计组件关系图main函数模拟downLoadprogressbar回调initBar初始化bar数组操作核心数据结构#define NUM 102       // 缓冲区长度(含终止符)#define BODY '='      // 进度条主体字符#define HEAD '>'      // 进度头部指示符#define TOP 100       // 进度最大值typedef void (*callback_t)(int);  // 标准化回调接口 利用函数指针实现回调。版本迭代解析v1版本悟原理progressBar.h头文件#pragma once#include <stdio.h>//缓冲区长度(含终止符)#define NUM 102    // 102 表示字符数组的长度 0-100 101个字符  末尾是\0, 因此大小是 102#define BODY '='      // 进度条主体字符#define HEAD '>'      // 进度头部指示符#define TOP 100       // 进度最大值extern void progressbar(int speed);  // extern 声明外部变量时必须加上  函数声明可加可不加#pragma once:防止头文件重复包含#define NUM 102 :102 表示字符数组的长度,0-100,共101个字符 ,字符串末尾是\0, 因此数组长度是102#define BODY '=':定义进度条的形体为=#define HEAD '>':定义进度条的头部为>#define TOP 100:定义进度条的区间长度,暂定为100通过宏的方式定义,可以方便的实现进度条样式的修改!progressBar.c源文件#include "progressBar.h"#include <string.h>#include <unistd.h>char bar[NUM] = {0};const char* label = "|/-\\";void progressbar(int speed) {    memset(bar, '\0', sizeof(bar));  //整体将字符串设为\0,可以方便的输出    int len = strlen(label);    int cnt = 0;    while (cnt <= TOP) {        //没有\n 就没有立即刷新,因为显示器默认是行刷新        printf("[%-100s][%d%%][%c]\r", bar, cnt, label[cnt % len]);        //预留出100空间,100s 默认是右对齐,进度条是反的, 用-100s解决        //用变长的字符串,循环覆盖输出,实现进度条光标移动的效果        //给进度条跑  %%显示百分号        fflush(stdout);        bar[cnt++] = BODY;  //更改进度条的风格        if (cnt < TOP)            bar[cnt] = '>';        // sleep(1);        usleep(speed);  // 100000微秒,用usleep实现更快的跑完    }    printf("\n");  //防止命令行提示符影响效果}char bar[NUM] = {0}:进度条主体使用长度不断改变的字符串来实现初始化为{0},这样就不用手动设置\0终止符了,用%s输出变化的字符串从0-100,恰好是char bar[NUM] = {0}字符数组中每个字符的下标每次循环内cnt会++利用cnt将0-100每个位置的字符都设置为进度条主体=。随着cnt++,数组内字符串的长度也在增长,再通过%s\r回车数组字符串,从而实现进度条的动态增长const char* label = "|/-\\"通过0-4五个字符的顺序循环输出,实现光标闪动的效果。printf("[%-100s][%d%%][%c]\r", bar, cnt, label[cnt % len])[%-100s]-:确保进度条不反方向增长100s:预留出100长度,供进度条字符串填充[%d%%]:%d:输出进度数字cnt%%:控制输出字符%[%c]:控制循环顺序输出|/-\\中的每个字符,实现光标闪动的效果用cnt % len实现0-4的循环\r:实现每次从行首开始输出,实现进度条的动态增长!fflush(stdout):每次printf过后,刷新缓冲区usleep(speed):usleep结合函数参数speed,实现进度条时长的控制main.c调用#include <unistd.h>#include "progressBar.h"int main(){    progressbar(20000);return 0;}效果如下:V2版本求拓展进度条最常见的适用场景就是在下载任务中,具体的运行方式应该是:下载任务向进度条函数传递下载任务已完成的进度百分比,进度条函数根据比率动态显示因此下载任务内一定要反复调用进度条程序。我们可以传入进度条函数的地址进行实现,也就是函数指针的回调函数。progressBar.h头文件#pragma once#include <stdio.h>//缓冲区长度(含终止符)#define NUM 102    // 102 表示字符数组的长度 0-100 101个字符  末尾是\0, 因此大小是 102#define BODY '='      // 进度条主体字符#define HEAD '>'      // 进度头部指示符#define TOP 100       // 进度最大值typedef void (*callback_t)(int);  //函数指针类型extern void progressbar(int rate);  // extern 声明外部变量时必须加上  函数声明可加可不加extern void downLoad(callback_t cb);extern void initBar();typedef void (*callback_t)(int) :callback_t是函数指针类型,我们可以拆解帮助理解:void (*)(int):其中:* :表示这是一个指针,且必须用括号包裹。否则会被解析为函数返回指针(如 void *func(int) 是返回 void* 的函数)(*):表示这是一个函数指针void:表示该函数的返回值为void,(int):表示该函数的参数类型为一个inttypedef void (*callback_t)(int)可以理解为typedef void (*)(int) callback_ttypedef:在typedef中,参数名会被省略,只保留类型。因此可以拆解为:typedef void (*)(int) callback_t:将void (*)(int)类型的指针定义为类型别名 callback_tprogressBar.c源文件#include "progressBar.h"#include <string.h>#include <unistd.h>// v2 应用char bar[NUM] = {0};const char* label = "|/-\\";void initBar() {    memset(bar, '\0', sizeof(bar));}void progressbar(int rate) {    if (rate < 0 || rate > 100)        return;    int len = strlen(label);    //用单个字符循环覆盖输出实现光标闪动    printf("[%-100s][%d%%][%c]\r", bar, rate, label[rate % len]);    fflush(stdout);    bar[rate++] = BODY;  //更改进度条的风格    if (rate < TOP)        bar[rate] = HEAD;}优化亮点:全局状态保存实现多任务支持initBar()提供重置进度条的能力动态头部指示符(>)增强视觉效果增加非法进度的判断if (rate < 0 || rate > 100) returnmain.c模拟多任务调度实现#include <unistd.h>#include "progressBar.h"// 模拟下载任务调用进度条void downLoad(callback_t cb) {     int total = 1000;    int curr = 0;  //目前curr需要从0开始    while (curr <= total) {        //进行某种下载任务,模拟时使用手动控制速度        usleep(50000);        int rate = curr * 100 / total;        cb(rate);  // 传入参数,回调展示进度        curr += 10;    }    printf("\n");  //防止命令行提示符影响效果}int main() {    printf("downLoan 1:\n");    downLoad(progressbar);    initBar();    printf("downLoan 2:\n");    downLoad(progressbar);    initBar();    printf("downLoan 3:\n");    downLoad(progressbar);    initBar();    return 0;}通过任务调用进度条,外部程序通过回调,调用进度条void (callback_t)(int),callback_t是函数指针类型。相当于typedef void (*)(int) callback_t,把callback_t变成函数指针类型的别名关键技术:函数指针实现回调机制速率换算算法(curr * 100 / total)时间控制(usleep微秒级延时)char bar[NUM]为全局数组,每次模拟download后,需initbar()函数重置保证独立性模块化设计,确保了可维护性。最终效果演示Makefile配置要点# 依赖关系# 依赖方法progressBar:*.c  @gcc $^ -o $@# clean和上面是独立的.PHONY:clean   clean:@rm -f progressBar结语关键知识点回顾控制台输出控制:回车符与换行符的灵活运用缓冲区机制:行缓冲特性与强制刷新策略可视化设计:进度条元素(主体、头部、百分比)的协同软件工程实践:模块化设计、回调机制、多任务支持扩展应用场景大数据处理进度监控嵌入式系统固件更新自动化测试进度反馈游戏加载界面优化​ 通过本文对Linux下C语言进度条程序的深度解析,我们系统性地掌握了控制台交互的核心技术。从回车换行符的底层原理到缓冲区刷新机制,从进度条动态显示到模块化设计,每一步都揭示了控制台可视化反馈的实现精髓。通过函数指针与回调机制的精妙配合,我们实现了多任务场景下的独立进度管理,展现了C语言在系统编程中的强大灵活性。​ 本项目的核心价值在于:不仅实现了基础的进度展示功能,更通过版本迭代演进,示范了软件开发的渐进式优化思路。在性能层面,未来可结合纳秒级延时控制与多线程安全机制提升精度;在交互层面,可考虑引入ANSI色彩代码或动态图标可进一步增强用户体验。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/2301_80064645/article/details/147645600
  • [技术干货] 【Linux】网络基础-转载
    一、网络的发展独立模式产生背景:在计算机发展的早期阶段,计算机系统主要以单机形式存在,每台计算机都是一个独立的个体,不与其他计算机进行数据通信和资源共享,这就是独立模式,当时的计算机主要用于科学计算和简单的数据处理,用户只能在本地使用计算机的硬件和软件资源特点独立性:每台计算机独立运行,有自己的处理器、存储器、输入输出设备等,数据和程序都存储在本地,不依赖其他计算机资源有限性:用户只能使用本地计算机的资源,如本地的硬盘空间、内存、打印机等,无法共享其他计算机的资源,资源利用效率较低功能局限性:主要用于完成本地的计算任务,如数值计算、文本处理等,无法实现多台计算机之间的协同工作和信息共享局域网LAN产生背景:随着计算机应用的逐渐普及,人们开始意识到多台计算机之间进行通信和资源共享的需求,于是局域网应运而生,20世纪70年代,一些科研机构和企业开始尝试将多台计算机连接在一起,形成一个小型的网络,以实现文件共享、打印机共享等功能特点地理范围有限:通常覆盖范围在几十米到几公里以内,如一个办公室、一栋建筑物或一个校园等高数据传输速率:一般能提供较高的数据传输速率,通常在10Mbps到1000Mbps甚至更高,能够快速地传输数据、文件和多媒体信息低误码率:由于传输距离较短,信号传输质量较好,误码率通常较低,一般在10⁻⁸到10⁻¹¹之间,保证了数据传输的准确性和完整性共享资源丰富:可以实现计算机之间的文件共享、打印机共享、数据库共享等,还能支持用户之间的信息交流和协同工作,如共享文档编辑、视频会议等易于管理和维护:网络规模相对较小,设备数量相对较少,因此网络的管理和维护相对简单,如网络配置、用户管理、故障排查等都比较容易实现广域网WAN产生背景:随着计算机网络应用的不断拓展,人们需要将不同地区、甚至不同国家的计算机连接起来,实现更广泛的信息交流和资源共享,广域网便在此背景下迅速发展起来,20世纪80年代,随着通信技术的进步,如光纤通信、卫星通信等的应用,使得远距离的计算机通信成为可能,广域网得到了快速发展特点地理范围广:覆盖范围可以跨越城市、国家甚至全球,能够连接不同地区的局域网和计算机系统,实现全球范围内的信息传输和资源共享多种通信介质:由于传输距离远,需要使用多种通信介质来实现数据传输,如电话线、光纤、卫星通信等,以满足不同距离和环境的通信需求数据传输速率差异大:不同的广域网技术和通信介质提供的数据传输速率有所不同,从较低的拨号上网速率(如56Kbps)到高速的光纤网络速率(如10Gbps甚至更高)都有,整体数据传输速率相对局域网较低,但随着技术的发展,高速广域网连接也越来越普及复杂的网络结构:由多个节点交换机、路由器和通信线路组成,网络结构复杂,涉及到不同地区的网络设备和通信链路的互联,需要采用复杂的路由算法和网络协议来实现数据的准确传输和网络的高效运行可扩展性强:能够容纳大量的计算机和局域网接入,具有很强的可扩展性,可以根据用户需求不断增加网络节点和扩展网络覆盖范围,以满足不断增长的通信和业务需求二、认识网络协议协议就是一种由某一方制定出来的,大家共同遵守的标准1、OSI七层模型OSI七层模型是一个开放性的通信系统互联参考模型,从下到上依次为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,其主要的功能就是帮助不同类型的主机实现数据传输,它最大的优点就是将服务、接口和协议这三个概念明确地区分出来,概念清楚,理论也比较完整,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯这是早期的标准,我们现在使用更加广泛的是TCP/IP五层模型层    名称    主要功能    协议及设备举例7    应用层    为应用程序提供网络服务,直接与用户和应用程序交互,负责处理特定的应用程序协议,如文件传输、电子邮件、远程登录等    HTTP、FTP、SMTP、DNS;网关6    表示层    处理数据的表示、转换和加密等,确保不同系统之间能够正确地理解和处理数据,包括数据格式转换、数据加密和解密、数据压缩和解压缩等功能    ASCII、JPEG、SSL/TLS5    会话层    建立、维护和管理会话,负责在不同主机上的应用程序之间建立、维持和终止会话连接,并提供会话同步和检查点功能,以确保数据传输的可靠性和连续性    NetBIOS、RPC4    传输层    提供端到端的通信服务,负责在不同主机上的应用程序之间进行数据传输,确保数据的可靠传输和流量控制,主要功能包括分段和重组数据、确认和重传、流量控制等    TCP、UDP;四层交换机3    网络层    负责网络之间的数据路由和寻址,将数据从源主机传输到目标主机,主要功能包括寻址、路由选择、分组转发等    IP、ICMP、IGMP;路由器2    数据链路层    将物理层接收到的信号转换为数据帧,并进行错误检测和纠正,负责在相邻节点之间传输数据帧,主要功能包括成帧、差错控制、流量控制、介质访问控制等    Ethernet、PPP、HDLC;网桥、交换机1    物理层    负责处理物理介质上的信号传输,定义了设备与物理介质之间的电气、机械、功能和规程特性,包括电缆、连接器、信号的传输与接收等    RS-232、RJ45、光纤;集线器、中继器2、TCP/IP五层模型TCP/IP五层模型从下到上依次为物理层、数据链路层、网络层、传输层、应用层层    名称    主要功能    协议及设备举例5    应用层    为用户提供网络应用服务,直接与用户和应用程序交互,负责处理特定的应用程序协议,如文件传输、电子邮件、远程登录等    HTTP、FTP、SMTP、DNS、SNMP;网关4    传输层    提供端到端的通信服务,负责在不同主机上的应用程序之间进行数据传输,确保数据的可靠传输和流量控制,主要功能包括分段和重组数据、确认和重传、流量控制等    TCP、UDP;四层交换机3    网络层    负责网络之间的数据路由和寻址,将数据从源主机传输到目标主机,主要功能包括寻址、路由选择、分组转发等    IP、ICMP、IGMP、ARP、RARP;路由器2    数据链路层    将物理层接收到的信号转换为数据帧,并进行错误检测和纠正,负责在相邻节点之间传输数据帧,主要功能包括成帧、差错控制、流量控制、介质访问控制等    Ethernet、PPP、HDLC、SLIP;网桥、交换机1    物理层    负责处理物理介质上的信号传输,定义了设备与物理介质之间的电气、机械、功能和规程特性,包括电缆、连接器、信号的传输与接收等    RS-232、RJ45、光纤、同轴电缆;集线器、中继器由于物理层我们考虑地比较少,所以有时候又把第一层和第二层看作一层,叫网络接口层,这也是有说法说TCP/IP四层模型的依据下图是操作系统结构图和TCP/IP五层模型相对应的图三、网络传输流程在网络传输时数据在每一层都要添加报头,以让该层知道这个数据可以在本层被解析本层的整个数据叫做报文,报文=报头+有效载荷发送数据时自上而下,也就是从应用层到链路层(硬件),由硬件发出解析数据时自下而上,也就是从链路层(硬件)到应用层,由硬件接收每个计算机上的网络模型一致,对应的层与层的协议是一致的,这也是保证我们能够正确解析报文的原因之一封装:几乎任何层的协议,都要提供将报头和有效载荷分离的能力分用:几乎任何层的协议,都要在报头中提供决定将自己的有效载荷交付给上层哪一个协议的能力1、同网段通信我们直接看图,对称分为两边,假设一个情境,左边用户1用着1号电脑(客户)给用着2号电脑的用户2(服务器)发了一个hello world,首先信息要到应用层,给上报头之后传到传输层,给上报头,以此类推到达链路层,以太网驱动程序(在网卡上)通过以太网的连接将数据发送到用户2(服务器)的网卡上,然后向上解析,通过报头找到对应的层,然后丢掉报头,最后解析出发出的内容2、跨网段通信以太网和令牌环是两种不同的局域网技术以太网的成本低,设备广泛普及,它在数据传输时的特点是多点接入、竞争式传输,要先监听网络介质是否空闲,空闲再发数据,如果两个设备同时发送数据会发生冲突,设备会检测到冲突并在随机时间后重试令牌环网设备较为昂贵,基本上已经被淘汰,它在数据传输时的特点是顺序接入、非竞争式传输,令牌在环形网络中按固定方向传递,只有持有令牌的设备才能发送数据,发送完成后,该设备会将令牌传递给下一个设备,避免了数据冲突,这里的令牌类似于我们的互斥锁我们这里只是想演示出不同类型的局域网之间的跨网通信的可行性,彰显网络设计结构的强大首先还是类似上面的,一个用户发送一个hello world,信息向下而行,发送到以太网当中,路由器连接在以太网中,通过以太网驱动程序将该信息捕捉,然后去掉以太网报头转移到IP层,再将有效载荷加上令牌环网报头通过令牌环驱动程序发送到令牌环网中(路由器只有第一层和第二层),然后被另一个用户的令牌环驱动程序接收并向上传递,最终传递到用户手中,这样就实现了不同用户跨网段的交流,以后所有局域之间的网络就算是不同的,我们通过路由器也是可以将用户发送的数据获取到,所以IP协议通过工作在IP层的路由器屏蔽了底层网络的差异化四、以太网通信1、MAC地址MAC 地址是固化在网络设备硬件(如网卡)中,用于在数据链路层唯一标识网络设备的一组物理地址,在相同局域下MAC地址保持它的唯一性2、通信原理以太网驱动程序发送数据的时候所带的紫色四角星报头,其实是一个结构体,实际上,几乎所有层的报头都是结构体,偶尔在轻量化的网络通信中报头的设计可能是一个类似int的内置类型,这个结构体中有两个信息,一个是发送数据网卡的MAC地址,一个是将要接收数据网卡的MAC地址,数据在以太网中是共享的,但是通过这个报头就可以实现定向发送,只有字段相同的网卡才可以接收该数据————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/s_little_monster/article/details/145917125
总条数:1203 到第 页
上滑加载中