Linux应用:程序运行
kill
kill命令的这种用法是向指定的进程发送特定信号编号的信号。信号在操作系统中是一种软件中断机制,用于通知进程发生了某种特定事件或要求进程执行特定操作。
kill - 信号编号 进程 ID
信号编号的含义:不同的信号编号代表不同的事件或操作。例如,常见的信号 1(SIGHUP)通常用于通知进程重新读取配置文件。当管理员修改了某个守护进程的配置文件后,可以使用kill -1 进程ID来让该进程重新加载新的配置,而无需重启进程。信号 2(SIGINT)对应着用户按下Ctrl+C组合键时发送给前台进程的中断信号,用于终止进程运行。信号 15(SIGTERM)是一种温和的终止进程信号,它通知进程应该正常退出,进程接收到该信号后,可以进行一些清理工作,如关闭打开的文件、释放资源等,然后再退出。
应用场景:在系统维护中,当需要让某个进程重新加载配置、暂停或继续运行等操作时,就可以通过发送相应信号编号的信号来实现。比如,在更新了一个 Web 服务器(如 Nginx)的配置文件后,使用kill -HUP 进程ID(HUP对应的信号编号是 1),Nginx 进程会重新读取配置文件,应用新的配置,而无需完全停止并重新启动服务,这样可以减少服务中断时间。
kill -9 xxx
kill -9 xxx是向进程 ID 为xxx的进程发送 9 号信号,即 SIGKILL 信号。这个信号是一种强制终止信号。
信号特性:SIGKILL 信号的特殊性在于它不能被进程捕获、忽略或阻塞。一旦进程接收到该信号,操作系统会立即终止该进程的运行,不会给进程留下进行任何清理操作的机会。这是一种非常强硬的终止进程方式,适用于那些陷入死锁、无限循环或其他无法通过正常方式终止的进程。
应用场景:当某个进程出现异常,如占用大量系统资源且无法响应正常的终止信号(如 SIGTERM),导致系统性能严重下降甚至可能影响其他正常进程运行时,就可以使用kill -9来强制终止该进程。例如,某个程序由于内存泄漏或逻辑错误进入了无限循环,不断消耗 CPU 资源,使用常规的kill -15(SIGTERM)无法使其停止,此时就可以使用kill -9 进程ID来快速结束这个失控的进程,恢复系统的正常运行。但使用kill -9时需要谨慎,因为突然终止进程可能会导致数据丢失或系统状态不一致等问题,尤其是对于一些涉及到文件操作、数据库事务处理的进程。
使用syslog来记录调试信息
syslog是 Linux 系统中用于记录系统日志的标准机制。应用程序可以通过syslog函数将调试信息、错误信息等记录到系统日志文件中。syslog函数可以设置不同的日志级别(如 DEBUG、INFO、WARN、ERROR、CRITICAL 等),以便区分不同类型的日志信息。通过查看系统日志文件,管理员和开发人员可以了解程序的运行情况,排查错误和进行系统维护。
openlog
openlog:该函数用于初始化 syslog 系统。它允许你设置一些基本的选项,比如日志的标识(用于在日志中标记该应用程序的消息)、日志的记录选项(例如是否将日志记录到控制台等)以及日志设施(指定消息的来源,比如是系统内核、用户级应用程序等)。
void openlog(const char *ident, int option, int facility);
ident是一个字符串,会出现在每条日志消息的开头,方便识别是哪个程序产生的日志;option是一些标志位的组合,用于设置日志记录的一些特性;facility指定日志消息的设施类型。
openlog 的参数:
ident:如前面所述,它是一个字符串,通常设置为程序的名称,方便在日志中识别。例如,如果你的程序叫 “myapp”,那么设置ident为 “myapp” 后,日志消息可能类似 “myapp: [日志内容]”。
option:它是一些常量的按位或组合。常见的选项有:
LOG_PID:在日志消息中包含进程 ID,这对于多进程程序追踪特定进程的日志很有用。
LOG_CONS:如果日志消息无法发送到 syslog 服务器,则将其输出到控制台,作为一种备份的日志输出方式。
LOG_NDELAY:立即打开与 syslog 服务器的连接,而不是等到第一次调用syslog时才打开。
facility:指定日志消息的来源设施,常见的设施有:
LOG_USER:一般用户级应用程序产生的消息,这是最常用的设施之一。
LOG_DAEMON:系统守护进程(后台运行的服务程序)产生的消息。
LOG_LOCAL0到LOG_LOCAL7:供本地使用的设施,可用于自定义应用程序的分类。
syslog
syslog:这是实际用于记录日志消息的函数。它可以根据之前openlog设置的选项和设施,将指定优先级和内容的消息记录到 syslog 中。
void syslog(int priority, const char *format, ...);
priority是消息的优先级,它结合了设施和严重性级别,比如LOG_ERR表示错误消息,LOG_DEBUG表示调试消息等。format和可变参数部分类似于printf函数,用于格式化日志消息内容。
syslog 的参数:
priority:它是设施和严重性级别的组合。严重性级别包括:
LOG_EMERG:系统不可用,这是最高级别的紧急消息。
LOG_ALERT:需要立即采取行动的问题。
LOG_CRIT:严重错误,比如硬件故障。
LOG_ERR:一般错误消息。
LOG_WARNING:警告消息,提示可能出现问题的情况。
LOG_NOTICE:正常但重要的事件。
LOG_INFO:一般信息性消息。
LOG_DEBUG:调试信息,用于开发和调试阶段,生产环境中一般不记录此类消息以减少日志量。
format 和可变参数:与printf函数类似,format是格式化字符串,可变参数是对应的值。例如:syslog(LOG_DEBUG, “Variable x has value %d”, x); 会将变量x的值以调试级别的日志记录到 syslog 中。
closelog
closelog:当你完成日志记录后,使用该函数关闭 syslog。它会释放与 syslog 相关的资源,确保程序正确清理。
void closelog(void);
代码示例
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>int main() {// 打开syslog,设置ident为"my_debug_app",使用LOG_PID选项,设施为LOG_USERopenlog("my_debug_app", LOG_PID, LOG_USER);int num = 10;// 记录调试信息syslog(LOG_DEBUG, "This is a debug message. Variable num = %d", num);// 假设发生错误if (num < 20) {syslog(LOG_ERR, "Error: num is less than 20");}// 关闭syslogcloselog();return 0;
}
首先通过openlog初始化 syslog,设置了日志标识为 “my_debug_app”,并使用LOG_PID选项在日志中包含进程 ID,设施选择LOG_USER。然后,通过syslog记录了一条调试信息和一条错误信息。最后,使用closelog关闭 syslog。运行这个程序后,你可以在系统的 syslog 文件(通常在/var/log/syslog,不同系统可能略有不同)中查看记录的日志信息。
cat /var/log/syslog

如何让程序不能被多次运行
可以通过多种方法实现程序不能被多次运行。一种常见的方法是使用文件锁机制,程序启动时尝试创建一个特定的锁文件,如果创建成功,则表示程序是首次运行;如果创建失败(说明锁文件已存在),则表示程序已经在运行,直接退出。在 Linux 系统中,可以使用flock函数来实现文件锁。另一种方法是通过进程间通信机制,如信号量,来判断是否已经有相同的程序在运行。
使用文件锁机制
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#include <cerrno>int main() {int fd;// 尝试打开锁文件,如果不存在则创建fd = open("myprogram.lock", O_WRONLY | O_CREAT, 0644);if (fd == -1) {perror("open");return EXIT_FAILURE;}// 使用flock函数尝试获取文件锁if (flock(fd, LOCK_EX | LOCK_NB) == -1) {if (errno == EWOULDBLOCK) {// 锁文件已存在,程序已在运行printf("Another instance of the program is already running.\n");close(fd);return EXIT_FAILURE;} else {perror("flock");close(fd);return EXIT_FAILURE;}}// 程序正常运行部分printf("Program is running...\n");// 模拟程序运行一段时间sleep(10);// 程序运行结束,释放文件锁并删除锁文件flock(fd, LOCK_UN);close(fd);unlink("myprogram.lock");return EXIT_SUCCESS;
}

首先尝试打开或创建一个名为 myprogram.lock 的文件。然后使用 flock 函数尝试获取排他锁(LOCK_EX),并且设置 LOCK_NB 标志以非阻塞方式获取锁。如果获取锁失败且错误码为 EWOULDBLOCK,则表示已有其他程序实例持有该锁,即程序已经在运行,此时输出提示信息并退出。若获取锁成功,则程序正常运行,运行结束后释放锁并删除锁文件。
使用信号量机制(进程间通信)
通过进程间通信机制,如信号量,来判断是否已经有相同的程序在运行
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <cerrno>#define SEM_KEY 12345union semun {int val;struct semid_ds *buf;unsigned short *array;
};int main() {int semid;struct sembuf sem_op; // 确保sem_op是sembuf类型的变量// 获取信号量集,如果不存在则创建semid = semget(SEM_KEY, 1, IPC_CREAT | 0666);if (semid == -1) {perror("semget");return EXIT_FAILURE;}// 初始化信号量的值为1union semun arg;arg.val = 1;if (semctl(semid, 0, SETVAL, arg) == -1) {perror("semctl");return EXIT_FAILURE;}// 尝试获取信号量sem_op.sem_num = 0;sem_op.sem_op = -1;sem_op.sem_flg = SEM_UNDO;if (semop(semid, &sem_op, 1) == -1) {if (errno == EAGAIN) {// 信号量已被占用,程序已在运行printf("Another instance of the program is already running.\n");return EXIT_FAILURE;} else {perror("semop");return EXIT_FAILURE;}}// 程序正常运行部分printf("Program is running...\n");// 模拟程序运行一段时间sleep(10);// 程序运行结束,释放信号量sem_op.sem_op = 1;if (semop(semid, &sem_op, 1) == -1) {perror("semop");return EXIT_FAILURE;}// 删除信号量集if (semctl(semid, 0, IPC_RMID) == -1) {perror("semctl");return EXIT_FAILURE;}return EXIT_SUCCESS;
}

首先通过 semget 函数获取或创建一个信号量集,键值为 SEM_KEY。然后使用 semctl 函数将信号量初始化为 1。在尝试运行程序时,通过 semop 函数尝试获取信号量,若获取失败且错误码为 EAGAIN,表示信号量已被占用,即程序已经在运行,输出提示信息并退出。若获取成功,则程序正常运行,运行结束后释放信号量并删除信号量集。
相关文章:
Linux应用:程序运行
kill kill命令的这种用法是向指定的进程发送特定信号编号的信号。信号在操作系统中是一种软件中断机制,用于通知进程发生了某种特定事件或要求进程执行特定操作。 kill - 信号编号 进程 ID 信号编号的含义:不同的信号编号代表不同的事件或操作。例如…...
【公务员考试】高效备考指南
高效备考指南:从计划制定到心态调整的全面攻略 公务员考试竞争激烈,备考过程既需要科学规划,也需要持之以恒的努力。结合多位高分考生的经验与专业机构的指导,本文整理了一套系统化的备考策略,涵盖目标设定、学习方法…...
基于SpringBoot+Vue3实现的宠物领养管理平台功能一
一、前言介绍: 1.1 项目摘要 随着社会经济的发展和人们生活水平的提高,越来越多的人开始关注并参与到宠物领养中。宠物已经成为许多家庭的重要成员,人们对于宠物的关爱和照顾也日益增加。然而,传统的宠物领养流程存在诸多不便&a…...
ens33没有分配到IPV4问题
方法一:手动为 ens33 接口分配 IP 地址 你能够借助 ip 命令手动给 ens33 接口分配 IP 地址。不过这种方式在系统重启之后就会失效。 步骤 查看网络信息 先查看一下当前网络的子网信息,例如网关地址和子网掩码等,你可以通过路由器管理界面或…...
SpringCloud 学习笔记2(Nacos)
Nacos Nacos 下载 Nacos Server 下载 | Nacos 官网 下载、解压、打开文件: 更改 Nacos 的启动方式 Nacos 的启动模式默认是集群模式。在学习时需要把他改为单机模式。 把 cluster 改为 standalone,记得保存! 启动startup.cmd Ubuntu 启动…...
Blender-MCP服务源码4-初始化项目解读
Blender-MCP服务源码4-初始化项目解读 上篇文章针对Blender开发框架完成了一个基础模板的搭建,并在Blender中成功进行了运行,那这个初始化项目中是如何进行页面效果呈现的,尝试手动进行功能精简来拆解项目代码 1-核心知识点 1)如…...
基于eNSP的IPV4和IPV6企业网络规划
基于eNSP的IPV4和IPV6企业网络规划 前言网络拓扑设计功能设计技术详解一、网络设备基础配置二、虚拟局域网(VLAN)与广播域划分三、冗余协议与链路故障检测四、IP地址自动分配与DHCP相关配置五、动态路由与安全认证六、广域网互联及VPN实现七、网络地址转…...
Vue3项目中可以尝试封装那些组件
在 Vue 3 项目中,组件的封装可以根据功能、复用性和业务需求进行划分。以下是一些常见的组件类型,适合封装为独立组件: 1. 基础 UI 组件 按钮 (Button) 封装不同样式、大小、状态的按钮。支持 disabled、loading 等状态。 输入框 (Input) 封…...
Web Component 教程(二):如何有效管理和使用自定义属性
前言 在现代前端开发中,Web Component 是一个强大的工具,可以帮助我们创建可重用的组件。Web Component 的一个重要特性是能够处理自定义属性,这使得我们能够灵活地控制组件的行为和外观。今天,我会通过一个通俗易懂的教程&#…...
C#特性和反射
1。特性概念理解? 特性(Attribute)是用于在【运行时】传递程序中各种元素(比如类、属性、方法、结构、枚举、组件等)行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所…...
蓝桥杯刷题周计划(第三周)
目录 前言题目一题目代码题解分析 题目二题目代码题解分析 题目三题目代码题解分析 题目四题目代码题解分析 题目五题目代码题解分析 题目六题目代码题解分析 题目七题目代码题解分析 题目八题目代码题解分析 题目九题目代码题解分析 题目十题目代码题解分析 前言 大家好&#…...
mysql5.x和mysql8.x查看和设置隔离级别
MySQL的隔离级别 级别标志值描述读未提交READ-UNCOMMITTED0存在脏读、不可重复读、幻读的问题读已提交READ-COMMITTED1解决脏读的问题,存在不可重复读、幻读的问题可重复读REPEATABLE-READ2mysql 默认级别,解决脏读、不可重复读的问题,存在幻…...
3.17学习总结
写了两道题 刚开始用的之前做组合输出的方法,时间超限了,想不出怎么优化,后面看了题解,代码如下 #include <stdio.h> #include <stdlib.h> int n,min2e9; int a[11],b[11]; //搜索 void hly(int s,int x,int y) {//当…...
Blender材质 - 层权重
层权重 混合着色器 可以让 面朝向的一面显示一种材质 另一面显示另一种材质 就能实现挺不错的材质效果 移动视角 材质会跟着变化 有点类似虚幻的视差节点BumpOffset...
【JavaEE】Spring Boot 日志
目录 一、日志概述二、使用日志2.1 打印日志2.2 日志框架2.2.1 门面 / 外观 模式 2.3 日志级别2.3.1 六大分类2.3.2 使用 2.4 日志级别配置2.5 日志的持久化2.6 日志文件分割2.7 日志文件格式2.8 Slf4j 简单打印日志 一、日志概述 ⽇志主要是为了发现问题, 分析问题, 定位问题…...
Qt中的 #include “xxxx.moc“ 说明
Qt中的 #include “xxxx.moc” 说明 在Qt开发中,有时会看到在cpp文件末尾包含 #include "xxxx.moc" 这样的代码。这种做法主要用于以下情况: 使用场景 当你在非头文件中定义了一个包含Q_OBJECT宏的类时,需要包含对应的.moc文件。…...
如何用solidworks画齿轮
齿轮还是很有技术含量的,专业名词太多看不懂, 只会画 (这个东西不能自己想当然画, 齿轮之间不啮合是很有问题的,会积累磨损) 步骤1 打开设计库里的toolbox 选择正齿轮,右键生成零件 需要改的有几个关键的地方,我是只知道内圆外圆所以,对我来说最重要的是标称轴直径 (即正中间…...
详解布隆过滤器及其模拟实现
目录 布隆过滤器 引入 概念 工作原理 模拟实现布隆过滤器 哈希函数集 布隆过滤器基本框架 add函数(添加到布隆过滤器中) contains函数(判断是否存在该值) 完整代码 布隆过滤器的删除 布隆过滤器的误判率 布隆过滤器的…...
element-plus中DatePicker 日期选择器组件的使用
1.选择某一天 代码: <el-date-pickerv-model"invoice_date"type"date"placeholder"请选择日期"style"width: 200px;"clearable /> 运行效果: 问题所在:这个数据的格式不是我们后端需要的那种&…...
SvelteKit 最新中文文档教程(4)—— 表单 actions
前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …...
力扣hot100二刷——二叉树
第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路,编程也很流利⭐⭐Basically 基本掌握需要稍作思考,或者看到提示方法后能解答⭐⭐⭐Sl…...
企业安全——数据泄露防护
0x00 前言 本篇对数据泄露防护方面的内容进行汇总和总结,为抛砖引玉的内容 0x01 数据隔离 数据隔离是防止数据泄露的一个非常好的方式,通常的隔离方式有 主机/服务器隔离网络隔离介质隔离 0x02 数据丢失预防 主要防止数据丢失的方法就是DLP&#x…...
字符串哈希从入门到精通
一、基本概念 字符串哈希是将任意长度的字符串映射为固定长度的哈希值(通常为整数)的技术,核心目标是实现O(1)时间的子串快速比较和高效查询。其本质是通过数学运算将字符串转换为唯一性较高的数值,例如: …...
C语言:编程设计猜数游戏
先由计算机想一个数给用户猜,如果猜对了,提示“right!”,猜错了,提示“wrong!及大小” 思路:用随机函数rand()取到计算机想的数 代码: #include <stdio.…...
地下车库智能停车位指引系统方案(还有缺陷)
一、系统核心技术架构 通过车牌识别+车位检测+室内定位+路径规划四大技术模块实现全自动指引: 二、关键技术方案 1. 车辆身份识别与入场触发 车牌识别(LPR)技术 入口处部署高清摄像头,自动识别车牌并关联车辆信息(如会员、临时车)。触发逻辑:识别成功后抬杆放行,同时…...
Docker 使用指南
Docker 是一种开源的容器化平台,它通过使用容器来进行应用程序的打包、分发和部署。下面是 Docker 的基本概念和优势: 容器化:Docker 使用容器来封装应用程序及其所有依赖项,使其能够在任何环境中运行,并且与底层系统隔…...
win10 c++ VsCode 配置PCL open3d并显示
win10 c VsCode配置PCL open3d并显示 一、效果图二、配置步骤2.1 安装vscode2.2 pcl-open3d配置2.3 vscode中设置 三、测试代码四、注意事项及后续 一、效果图 二、配置步骤 2.1 安装vscode vscode下载链接 下载中文插件、c相关插件 2.2 pcl-open3d配置 1)下载…...
Vala 开发环境搭建
介绍 Vala 是一种使用现代高级抽象的编程语言,与用 C 语言编写的应用程序和库相比,没有施加额外的运行时要求,也不需要使用不同的 ABI。 Vala 使用 GObject 类型系统,并具有额外的代码生成例程,使面向 GNOME 堆栈变得简…...
【网页】自制流光卡片
概述 小红书有个博主自己搞的笔记排版工具叫“流光卡片”,类似的还有个Markdown排版工具叫MD2Card。 我这个版本类似,但是自己写的东西,控制性更好。 初期就写了个静态页面,后期结合Godot快速生成,并可能结合JS库&a…...
【数据结构】栈与队列:基础 + 竞赛高频算法实操(含代码实现)
什么是栈?什么是队列? 什么是先进后出?什么是先进先出? 了解基础之后,又如何用来写算法题? 带着这些疑问,让我带领你,走进栈与队列的世界 栈与队列 栈: 1、栈的基本…...
