Go语言(二十一) 常见的模块使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言(二十一) 常见的模块使用相关的知识,希望对你有一定的参考价值。
模块使用
执行系统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
",err)
return
}
//打印返回结果
fmt.Printf("%s
",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
",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)
}
}
以上是关于Go语言(二十一) 常见的模块使用的主要内容,如果未能解决你的问题,请参考以下文章
Golang✔️走进 Go 语言✔️ 第二十一 延迟处理 & 正则表达式