Linux C/C++ timeout命令实现(运行具有时间限制)

news2024/9/24 23:11:55

Linux附带了大量命令,每个命令都是唯一的,并在特定情况下使用。Linux timeout命令的一个属性是时间限制。可以为任何命令设置时间限制。如果时间到期,命令将停止执行。

如何使用timeout命令

我们将解释如何使用Linux timeout命令

timeout [OPTION] DURATION COMMAND [ARG]…
timeout [OPTION]

DURATION可以是正整数或浮点数,后跟可选的单位后缀:

s - seconds (default)
m - minutes
h - hours
d - days

未使用单位时,默认为秒。如果持续时间设置为零,则禁用关联的超时。

其他选项

DESCRIPTION
       --preserve-status
              以与COMMAND相同的状态退出,即使命令超时

       --foreground
              当不直接从shell提示符运行超时时,允许COMMAND从TTY读取并获得TTY信号;在此模式下,COMMAND的子级不会超时

       -k, --kill-after=DURATION
              如果COMMAND仍在运行,也发送KILL信号在发出初始信号后很久

       -s, --signal=SIGNAL

              指定超时时要发送的信号;SIGNAL可以是类似“HUP”的名称或数字;有关信号列表,请参见“kill-l”

       --help
              显示此帮助并退出 

       --version
              输出版本信息并退出

如何使用timeout命令的基本示例

  • 1.设置定时间后终止命令:

timeout 30 ping www.baidu.com

通过使用超时,我们可以确保ping不会一直运行,占用网络带宽并纠缠任何正在ping的设备。

此命令允许ping运行五秒钟。它正在对www.baidu.com的域名进行ping,用于研究本文的测试网络上。

如果程序的执行在超时终止之前结束,超时可以将退出代码从程序传递回shell,要实现这一点,程序必须自动停止(换句话说,它不会因超时而终止),并且必须使用–preserve-status选项。

如果使用值为5的-c(count)选项,ping将只发出5个请求。如果我们给超时一分钟,ping肯定会自行终止。然后我们可以使用echo检查退出值。

  • 2.发送正确的信号

当timeout想要停止程序时,它会发送SIGTERM信号。这礼貌地要求程序终止。某些程序可能选择忽略SIGTERM信号。

我们可以通过请求超时来发送SIGKILL信号来实现这一点。可以使用-s(signal)选项告诉超时以发送SIGKILL信号。

timeout -s SIGKILL 20 sudo tcpdump -i ens33 -n -w 20230212.pcap


我们可以使用tcpdump 抓包的默认选项运行20秒后,发送SIGKILL信号终止进程。

  • 3.尝试使用SIGTERM停止程序

我们使用-k(kill after)选项。-k选项需要一个时间值作为参数。在这个命令中,我们要求超时,让dmesg运行30秒,然后用SIGTERM信号终止它。如果dmesg在40秒后仍在运行,则意味着外交SIGTERM被忽略,超时应发送SIGKILL以完成任务。

timeout -k 40 30 dmesg -w


dmesg运行30秒,并在收到SIGTERM信号时停止。

Linux C/C++ timeout命令实现

...
int main(int argc, char** argv) {
...
    for(int i=1;i<argc;i++) {
    	char* arg = argv[i];
    	if(strlen(arg) <= 0) continue;
    	
    	if(arg[0] == '-') {
			if(!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
				printHelp(argv[0]);
				return EXIT_SUCCESS;
			} else if(!strcmp(arg, "-9") || !strcmp(arg, "--kill")) {
				sig_kill = SIGKILL;
	...
			} else {
				fprintf(stderr, "Illegal argument: %s\n", arg);
				return EXIT_FAILURE;
			}
    	} else {
			/* 
			没有更多选项。检查是否有足够的剩余参数
			基本语法是/程序[OPTIONS]超时程序[ARGS]
			而超时和程序是强制性的  */
    		if (i+2 > argc) {		// 检查是否给出超时和程序
				fprintf(stderr, "Not enough arguments. Check %s --help, if you need help\n", argv[0]);
				if(i+1 > argc) {
					// 检查参数是否为数字
					fprintf(stderr, "  Missing: TIMEOUT PROGRAM\n");
				} else {
					if(is_numeric(argv[i]))
						fprintf(stderr, "  Missing: PROGRAM\n");
					else
						fprintf(stderr, "  Missing: TIMEOUT\n");
				}
				return EXIT_FAILURE;
    		} else {
				int seconds = atoi(argv[i]);
				if(seconds < 0) {
					fprintf(stderr, "Timeout cannot be negative");
					return EXIT_FAILURE;
				}
				timeout = (unsigned int)seconds;
				
				// 合并程序和可选程序参数
				for(int j=i+1;j<argc;j++)
					command = strappend(command, argv[j]);
				
				break;
			}
    	}
    	
    }
    
    // 检查程序参数
	if(command == NULL || strlen(command) <= 0) {
		fprintf(stderr, "Not enough arguments. Check %s --help, if you need help\n", argv[0]);
		fprintf(stderr, "  Missing: TIMEOUT PROGRAM\n");
		return EXIT_FAILURE;
	}
    
    // Fork守护程序(如果需要)
    if (daemonize) {
    	fork_daemon();
    }
    
    
    ...

		int status;
		pid_t wait_status;
		
		// 信号处理器
		signal(SIGINT, sig_handler);
		signal(SIGTERM, sig_handler);
		signal(SIGALRM, sig_handler);
		
		if(verbose) printf("Child process forked with pid %d.\n", proc_pid);
		
		// 设置报警
		if(timeout > 0) alarm(timeout);
		wait_status = waitpid(proc_pid, &status, 0);		// Wait for child
		runtime += millis();
		if(wait_status < 0) {
			fprintf(stderr, "Error waiting for process: %s\n", strerror(errno));
			return EXIT_FAILURE;
		}
		status = WEXITSTATUS(status);		// 获取实际退出状态
		if(status != 0) {
			if(verbose) fprintf(stderr, "Process exited with status %d after %ld milliseconds\n", status, runtime);
			return status;
		} else {
			if(verbose) printf("Process completed after %ld milliseconds\n", runtime);
			return status;
		}
	}
    
    ...
}
...
static void sig_handler(int sig_no) {
	switch(sig_no) {
		case SIGALRM:
			// Timeout
			if(verbose)
				printf("TIMEOUT after %ld milliseconds.\n", runtime+millis());
			else
				printf("TIMEOUT\n");
			terminate_process();
			exit(EXIT_FAILURE);
			break;
		case SIGINT:
		case SIGTERM:
			if(proc_pid <= 0) exit(EXIT_FAILURE);
			if(verbose) printf("Program termination request\n");
			if(proc_pid > 0) kill(proc_pid, sig_no);
			exit(EXIT_FAILURE);
			return;
	}
}

...

编译运行


If you need the complete source code of timeout, please add WeChat number (c17865354792)​

总结

总结

timeout是一个命令行实用程序,它运行指定的命令,如果在给定的时间段后仍在运行,则终止该命令。

Welcome to follow WeChat official account【程序猿编码

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

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

相关文章

七、Git远程仓库操作——团队成员内协作

1. github远程协作的两种方式 前面我写的笔记&#xff0c;都是自己一个人在玩&#xff0c;无论是本地操作还是推送到远程都是自己推送到自己的仓库。 如果是别人拥有这个仓库&#xff0c;而我想对这个仓库的内容更改后&#xff0c;然后想推送更新到这个仓库&#xff0c;我们要…

【随笔】我迟到的2022年度总结:突破零粉丝,1个月涨粉1000+,2023年目标3万+

前言 我是21年12月注册的csdn&#xff0c; 作为用户平时看看文章&#xff0c;从未参与过写文章这件事。 但这一年的时间我见证了很多新号的崛起&#xff0c;有的号我平时关注比较多&#xff0c;看着他们从零粉丝突破了三万甚至五万的粉丝量。 在csdn上遇到了我的贵人&#x…

位运算 | 1356. 根据数字二进制下 1 的数目排序

LeetCode 1356. 根据数字二进制下 1 的数目排序 给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。如果存在多个数字二进制中 1 的数目相同&#xff0c;则必须将它们按照数值大小升序排列。 文章讲解https://www.programmercarl.com/1356.%…

【微电网】基于风光储能和需求响应的微电网日前经济调度(Python代码实现)

目录 1 概述 2 知识点及数学模型 3 算例实现 3.1算例介绍 3.2风光参与的模型求解 3.3 风光和储能参与的模型求解 3.5 风光储能和需求响应都参与模型求解 3.6 结果分析对比 4 Python代码及算例数据 1 概述 近年来&#xff0c;微电网、清洁能源等已成为全球关注的热点…

Linux Vim编辑器基础讲解

目录 vim三个模式 命令模式 输入模式&#xff08;insert 插入模式、编辑模式&#xff09; 末行模式 编辑简单文档 什么是vim Vim是文本编辑器&#xff0c;是Linux上最常用的文本编辑器 Vim可以建立、编辑、显示文件 绝大多数Linux都会携带vim或者vi vim编辑器和vi编辑器的…

windbg-应用层实时调试

调试符号windbg使用一个或多个目录来存放符号条件&#xff0c;并使用环境变量_NT_SYMBOL_PATH来指向这些环境变量的位置&#xff0c;对操作系统内部模块的符号文件&#xff0c;一般用http://msdl.microsoft.com/download/symbols配置如下&#xff1a;SRV*C:\Symbols*http://msd…

手把手教你部署ruoyi前后端分离版本

下载源码&#xff08;当前版本3.8.5&#xff09;RuoYi-Vue: &#x1f389; 基于SpringBoot&#xff0c;Spring Security&#xff0c;JWT&#xff0c;Vue & Element 的前后端分离权限管理系统&#xff0c;同时提供了 Vue3 的版本 (gitee.com)创建数据库(一定要是这三个&…

【STM32】【HAL库】遥控关灯3 遥控器

相关连接 【STM32】【HAL库】遥控关灯0 概述 【STM32】【HAL库】遥控关灯1主机 【STM32】【HAL库】遥控关灯2 分机 【STM32】【HAL库】遥控关灯3 遥控器 需求 硬件遥控器 控制一个灯的开关(2个按键),发射RF433或红外 使用纽扣电池供电 一键启动,低待机功耗 硬件设计 一键…

推荐系统开源工具RecBole学习

文章全文首发&#xff1a;码农的科研笔记&#xff08;公众号&#xff09; RecBole是由AI Box团队开发的基于Pytorch的推荐系统算法库。该框架从数据处理、模型开发和算法训练都有涉及&#xff0c;能方便进行算法构建和实验对比。 数据组织形式 RecBole约定了一个统一、易用的数…

发生异常: AttributeError ‘xxx’ object has no attribute ‘ooo’

python 发生异常: AttributeError ‘xxx’ object has no attribute ‘ooo’ 原因&#xff1a; 函数调用发生在变量定义之前 示例分析&#xff1a; 在apple.py文件中代码如下&#xff1a; class Apple():def __init__(self):self.eat()self.pricedef eat(self):print("吃…

Spring Security in Action 第十八章 手把手OAuth2应用

本专栏将从基础开始&#xff0c;循序渐进&#xff0c;以实战为线索&#xff0c;逐步深入SpringSecurity相关知识相关知识&#xff0c;打造完整的SpringSecurity学习步骤&#xff0c;提升工程化编码能力和思维能力&#xff0c;写出高质量代码。希望大家都能够从中有所收获&#…

Java:SpringMVC的使用(2)

目录第十二章 REST风格CRUD练习12.1 搭建环境12.2 实现功能思路第十三章 SpringMVC消息转换器13.1 消息转换器概述13.2 使用消息转换器处理请求报文(1) 使用RequestBody获取请求体(2) 使用HttpEntity\<T>获取请求体及请求头13.3 使用消息转换器处理响应报文(1) 使用Respo…

llvm 创建外部调用函数方法

llvm 创建外部调用函数方法 2023-02-12 15:26:19 sizaif 文章目录llvm 创建外部调用函数方法法一:声名参数类型及函数类型在llvm IR中处理并调用函数:外部函数&#xff1a;法二声明函数在llvm IR中处理并函数调用外部函数法一: 声名参数类型及函数类型 // Fun Ty static Fun…

【CS224W】(task3)NetworkX工具包实践

note 节点可以为任意可哈希的对象&#xff0c;比如字符串、图像、XML对象&#xff0c;甚至另一个Graph、自定义的节点对象。通过这种方式可以自由灵活地构建&#xff1a;图为节点、文件为节点、函数为节点&#xff0c;等灵活的图形式。暂时省略&#xff1a;【B5】计算机网络图…

vue3学习资料整理

一、一个后端程序员为什么要学习前端&#xff1f; 1.网上找到的学习理由 《Java后端的我也要学Node.js 了》 https://blog.csdn.net/yusimiao/article/details/104689007 《nodejs后端开发的优缺点&#xff08;nodejs的概念与特征详解&#xff09;》 https://www.1pindao.co…

2023级浙江大学MEM提面最新经验分享

一、个人背景背景&#xff1a;本人毕业于某211大学工程管理相关专业&#xff0c;目前定居在杭州&#xff0c;在某汽车制造公司工作&#xff0c;负责研发无人驾驶项目。我申请的是浙大MEM提前批面试&#xff0c;因为通过提面优秀资格顺利上岸录取&#xff0c;之前感到对自己有帮…

Java、JSP动漫网站的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;随着科技的迅速发展&#xff0c;计算机技术已应用到社会的各个领域。随着计算机技术和通信技术的迅速发展&#xff0c;网络的规模也逐渐增大&#xff0c;网络的元素也随之不断增加&#xff0c;有的利用其通信&#xff0c;有的利用其…

【软件测试开发】Junit5单元测试框架

目录1. 注解Test 注解BeforeEach BeforeAllAfterEach AfterAll2. 断言 assertassertequalsassertTrue assertFalseassertNull assertNotNull3. 用例执行顺序方法排序&#xff0c;通过 Order 注解来排序4. 测试套件 Suite5. 参数化单参数stringsints6. 参数化多参数CsvSourceCsv…

File类

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 ✈️推荐一款模拟面试&#xff0c;刷题神器…

2. SpringMVC 请求与响应

文章目录1. 请求映射路径2. 请求参数2.1 get 请求发送普通参数2.2 post 请求发送普通参数2.3 五种类型的参数传递2.4.1 普通参数2.4.2 POJO 数据类型2.4.3 嵌套 POJO 类型参数2.4.4 数组类型参数2.4.5 集合类型参数3. json 数据传输参数&#xff08;重点&#xff09;3.1 传输 j…