【go】`time`和`os/exec`包使用例子

如何简单实现⼀个定时器程序,能够实现在指定时间执⾏指定程序,如果程序重启怎么办?

实现方案

可以使用Go语言内置的timeos/exec包来实现定时器程序。

实现分析

  1. 解析传入的程序二进制文件路径和计划时间。
  2. 计算当前时间和计划时间的时间差,使用time包中的定时器函数time.After()来设置定时器,等待时间差到达后触发定时器事件。
  3. 在定时器事件中,使用os/exec包中的函数来执行指定的程序,若启动失败可以设置重新启动。

对于程序重启,对本程序功能并不影响:

  • 本定时器重启的场景:定时任务时间等待时间差是在程序启动时实时计算的,若重启了还是会重新计算当前时间差再次计时;
  • 执行目标程序重启,当前计时器程序目的就是去执行目标程序,目标程序重启不影响本程序功能。

实现步骤

准备一个 “可执行程序”

package main
import "fmt"
func main() {
	fmt.Println("测试拉起二进制成功!!!!")
}

编译出可执行程序:(假设路径是"D:/test/testCall.exe")

 go build .\testCall.go

实现定时器程序

package main

import (
	"fmt"
	"os"
	"os/exec"
	"time"
)

const (
	argNum = 3
	retryCount = 3
)

func main() {
	// 解析传入的程序二进制文件路径和计划时间
	if len(os.Args) < argNum {
		fmt.Println("Usage: go run main.go [binary_path] [plan_time]")
		os.Exit(1)
	}
	binaryPath := os.Args[1]

	loc, _ := time.LoadLocation("Asia/Shanghai")
	planTime, err := time.ParseInLocation("2006-01-02 15:04:05", os.Args[2], loc)
	if err != nil {
		fmt.Println("Error: Invalid plan time format,", err)
		os.Exit(1)
	}
	
	// 启动程序时记录启动时间
	now := time.Now().Local().UTC()
	fmt.Println("Info: now = ", now)
	fmt.Println("Info: planTime = ", planTime)
	// 计算时间差并设置定时器
	duration := planTime.Sub(now)
	fmt.Println("Info: duration =", duration)

	if duration > 0 {  // 是否需要定时器,防止是定时器程序重启过
		timer := time.NewTimer(duration)
		fmt.Println("Info: waiting timer")
		// 等待定时器事件
		<-timer.C
	}

	// 执行指定程序
	for i := 0; i < retryCount; i++ { // 最多尝试执行3次
		cmd := exec.Command(binaryPath)
		output, err := cmd.Output()
		if err == nil {
			fmt.Println(string(output))
			fmt.Println("Even: binary executed successfully")
			return
		}
		fmt.Println("Warn: Failed to execute program:", err)
		time.Sleep(5 * time.Second) // 等待5秒再尝试执行
	}
	fmt.Println("Error: binary execution failed")
}

执行程序:

 go run main.go  "D:/test/testCall.exe" "2024-08-26 19:48:05"

或者 go build 编译出来后执行:

.\main.exe "D:/test/testCall.exe" "2024-08-26 19:48:05"

测试结果

Info: now =  2024-08-26 20:42:55.4405164 +0800 CST
Info: planTime =  2024-08-26 19:48:05 +0800 CST
Info: duration = -54m50.4405164s
测试拉起二进制成功!!!!

Even: binary executed successfully

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值