Go语言(二十一) 常见的模块使用
时间:2022-07-25
本文章向大家介绍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:%vn",err)
return
}
//打印返回结果
fmt.Printf("%sn",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=%sn",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)
}
}
- 程序员面试50题(1)—查找最小的k个元素[算法]
- Netty4自带编解码器详解
- C和指针小结(C/C++程序设计)
- Netty-整合Protobuf高性能数据传输
- Netty-整合kryo高性能数据传输
- 40个重要的HTML 5面试问题及答案
- js调用原生API--陀螺仪和加速器
- OpenDaylight开发-DataStoreChange监听器三种类型
- express模拟接口
- spring boot开发的日志系统
- elasticsearch 5.0.1安装analysis-ik分词器
- Spring Cloud中Feign如何统一设置验证token
- laravel+react+webpack+babel+gulp的配置
- OpenvSwitch系列之浅析main函数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python 穷举指定长度的密码例子
- Android 高仿微信朋友圈拍照上传功能
- android的ListView点击item使item展开的做法的实现代码
- Android NavigationView头部设置监听事件
- android如何取得本地通讯录的头像的原图的实现代码
- 取消Android Studio项目与SVN关联的方法
- Android编程实现获取当前系统语言及地区并更改语言的方法
- Android Studio绑定下拉框数据详解
- python中的socket实现ftp客户端和服务器收发文件及md5加密文件
- Android XRecyclerView实现多条目加载
- python3安装OCR识别库tesserocr过程图解
- Android studio 3.0上进行多渠道打包遇到的问题小结(超简洁版)
- Python自动重新加载模块详解(autoreload module)
- python自动脚本的pyautogui入门学习
- Android手机号码输入框(满11位自动跳到下个输入框)实例代码