分享
  1. 首页
  2. 文章

Go语言(二十一) 常见的模块使用

wx5b285b48ed74e · · 994 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

模块使用

执行系统shell命令

  • 使用os/exec模块
package main
import (
 "fmt"
 "os/exec"
)
func main() {
 var (
 cmd *exec.Cmd
 err error
 )
 cmd = exec.Command("/bin/bash","-c","echo hello")
 err = cmd.Run()
 if err != nil {
 fmt.Println(err)
 }
 fmt.Println(err)
}
  • 获取命令执行的返回结果
package main
import (
 "fmt"
 "os/exec"
)
func main() {
 var (
 cmd *exec.Cmd
 output []byte
 err error
 )
 //生成cmd
 cmd = exec.Command("/bin/bash","-c","sleep 1;ls -l ~/")
 if output,err = cmd.CombinedOutput();err != nil {
 fmt.Printf("cmd return faild,err:%v\n",err)
 return
 }
 //打印返回结果
 fmt.Printf("%s\n",string(output))
}
  • 多线程
package main
import (
 "context"
 "fmt"
 "os/exec"
 "time"
)
type result struct {
 err error
 output []byte
}
func main() {
 var (
 cmd *exec.Cmd
 ctx context.Context
 cancelFunc context.CancelFunc
 resultChan chan *result
 res *result
 )
 resultChan = make(chan *result,1000) //创建一个结果队列
 ctx,cancelFunc = context.WithCancel(context.TODO())
 go func() {
 var (
 output []byte
 err error
 )
 cmd = exec.CommandContext(ctx,"/bin/bash","-c","sleep 2;echo hello")
 //执行任务,捕获输出
 output,err = cmd.CombinedOutput()
 //把输出结果输出给main协程
 resultChan <- &result{
 err: err,
 output: output,
 }
 }()
 //1秒取消上下文
 time.Sleep(time.Second*3)
 //取消上下文
 cancelFunc()
 //在main协程里等待子协程的退出,并打印任务执行的结果
 res = <- resultChan
 fmt.Println(res.err,string(res.output))
 //fmt.Printf("err=%v,res=%s\n",res.err,string(res.output))
}

cron模块的使用

  • 执行单个任务
package main
import (
 "fmt"
 "github.com/gorhill/cronexpr"
 "time"
)
func main() {
 var (
 expr *cronexpr.Expression
 err error
 )
 //每分钟执行一次
 /*
 if expr,err = cronexpr.Parse("* * * * *");err != nil {
 fmt.Println(err)
 return
 }
 */
 //每五秒执行一次,支持到年的配置
 if expr,err = cronexpr.Parse("*/5 * * * * * *");err != nil {
 fmt.Println(err)
 return
 }
 //获取当前时间
 now := time.Now()
 //下次执行时间
 nextTime := expr.Next(now)
 //等待这个定时器超时
 time.AfterFunc(nextTime.Sub(now), func() {
 fmt.Println("被调度了:",nextTime)
 })
 time.Sleep(time.Second*5)
}
  • 执行多个任务
package main
import (
 "fmt"
 "github.com/gorhill/cronexpr"
 "time"
)
type CronJob struct {
 expr *cronexpr.Expression
 nextTime time.Time
}
func main() {
 //需要一个调度协程,定时检查所有的cron任务,谁过期执行谁
 var (
 cronJob *CronJob
 expr *cronexpr.Expression
 now time.Time
 scheduleTable map[string]*CronJob
 )
 scheduleTable = make(map[string]*CronJob) //初始化调度表
 //获取当前时间
 now = time.Now()
 // 1.定义两个cron
 expr = cronexpr.MustParse("*/5 * * * * * *")
 cronJob = &CronJob{
 expr: expr,
 nextTime: expr.Next(now),
 }
 //将任务1注册到调度表
 scheduleTable["job1"] = cronJob
 // 2.定义两个cron
 expr = cronexpr.MustParse("*/5 * * * * * *")
 cronJob = &CronJob{
 expr: expr,
 nextTime: expr.Next(now),
 }
 //将任务1注册到调度表
 scheduleTable["job2"] = cronJob
 //启动一个调度协程
 go func() {
 var(
 jobName string
 cronJob *CronJob
 now time.Time
 )
 //定期检查调度表
 for {
 now = time.Now()
 for jobName,cronJob = range scheduleTable {
 //判断是否过期
 if cronJob.nextTime.Before(now) || cronJob.nextTime.Equal(now) {
 //启动一个协程,执行这个任务
 go func(jobName string) {
 fmt.Println("执行:",jobName)
 }(jobName)
 }
 //计算下一次的调度时间
 cronJob.nextTime = cronJob.expr.Next(now)
 fmt.Println(jobName,"下次执行的时间:",cronJob.nextTime)
 }
 }
 //睡眠100毫秒,进入下一次循环
 select {
 case <- time.NewTimer(100*time.Millisecond).C: //将在100毫秒可读,返回
 }
 }()
 time.Sleep(100*time.Second)
}

etcd的使用

  • 与etcd建立连接
package main
import (
 "fmt"
 "github.com/coreos/etcd/clientv3"
 "time"
)
func main() {
 var (
 config clientv3.Config
 client *clientv3.Client
 err error
 )
 //客户端配置
 config = clientv3.Config{
 Endpoints: []string{"192.168.56.11:2379"},
 DialTimeout: 5*time.Second,
 }
 //建立连接
 if client,err = clientv3.New(config);err != nil {
 fmt.Println(err)
 return
 }
 client = client
}
  • 插入键值对
package main
import (
 "context"
 "fmt"
 "github.com/coreos/etcd/clientv3"
 "time"
)
func main() {
 var (
 config clientv3.Config
 client *clientv3.Client
 err error
 kv clientv3.KV
 putResp *clientv3.PutResponse
 )
 //建立连接
 config = clientv3.Config{
 Endpoints: []string{"192.168.56.11:2379"},
 DialTimeout: 5*time.Second,
 }
 if client,err = clientv3.New(config);err!=nil {
 fmt.Println(err)
 return
 }
 //读写etcd的键值对
 kv = clientv3.NewKV(client)
 //kv.Put(ctx context.Context())
 if putResp,err = kv.Put(context.TODO(),"/cron/jobs/job1","hello",clientv3.WithPrefix());err != nil {
 fmt.Println(err)
 return
 }else {
 fmt.Println(putResp.Header.Revision)
 if putResp.PrevKv != nil {
 fmt.Println("PrevValue:",string(putResp.PrevKv.Value))
 }
 }
}
  • 读写etcd键值对
package main
import (
 "context"
 "fmt"
 "github.com/coreos/etcd/clientv3"
 "time"
)
func main() {
 var (
 config clientv3.Config
 client *clientv3.Client
 err error
 kv clientv3.KV
 getResp *clientv3.GetResponse
 )
 //建立连接
 config = clientv3.Config{
 Endpoints: []string{"192.168.56.11:2379"},
 DialTimeout: 5 * time.Second,
 }
 //建立客户端
 if client, err = clientv3.New(config); err != nil {
 fmt.Println(err)
 return
 }
 //用于读写etcd键值对
 kv = clientv3.NewKV(client)
 if getResp,err = kv.Get(context.TODO(),"/cron/jobs/job1",/*clientv3.WithCountOnly())*/);err !=nil {
 fmt.Println(err)
 return
 }else {
 fmt.Println(getResp.Kvs,getResp.Count)
 }
}
  • 按目录读取键值对
package main
import (
 "context"
 "fmt"
 "github.com/coreos/etcd/clientv3"
 "time"
)
//按目录获取
func main() {
 var (
 config clientv3.Config
 client *clientv3.Client
 err error
 kv clientv3.KV
 getResp *clientv3.GetResponse
 )
 //建立连接
 config = clientv3.Config{
 Endpoints: []string{"192.168.56.11:2379"},
 DialTimeout: 5 * time.Second,
 }
 //建立客户端
 if client, err = clientv3.New(config); err != nil {
 fmt.Println(err)
 return
 }
 //用于读写etcd键值对
 kv = clientv3.NewKV(client)
 //取/cron/jobs/为前缀的所有key
 if getResp,err = kv.Get(context.TODO(),"/cron/jobs",clientv3.WithPrefix());err != nil {
 fmt.Println(err)
 return
 }else {
 //获取所有的kvs
 fmt.Println(getResp.Kvs)
 }
}

有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:wx5b285b48ed74e

查看原文:Go语言(二十一) 常见的模块使用

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
994 次点击
1 回复 | 直到 2025年05月12日 09:01:55
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏