当前位置: 首页 > news >正文

东莞政务网站建设方案网络链接推广

东莞政务网站建设方案,网络链接推广,无锡网站开发公司,行业平台网站建设先说结论 1. golang提供了syscall包来实现文件/目录的加锁,解锁 2. syscall包属于文件锁,是比较底层的技术,并不能在所有操作系统上完全实现,linux上实现了,windows下面就没有 3. 加锁时调用syscall.Flock(fd&#…

先说结论

1. golang提供了syscall包来实现文件/目录的加锁,解锁

2. syscall包属于文件锁,是比较底层的技术,并不能在所有操作系统上完全实现,linux上实现了,windows下面就没有

3. 加锁时调用syscall.Flock(fd,syscall.LOCK_EX),解锁时调用syscall.Flock(fd, syscall.LOCK_UN)

4. 加锁成功后,对加锁的文件fd进行Close()操作同样会释放锁,切记

代码实现

锁的定义如下内部两个变量:文件/目录的全路径名,文件对象

// 文件锁/目录锁
type DirLock struct {
    dir     string        // 文件/目录的全路径名
    f       *os.File    // 文件对象
}

加锁的实现

核心代码是 syscall.Flock(int(f.Fd()), LOCK_EX|syscall.LOCK_NB),注意其中的标记

LOCK_EX :加锁标记。只有一个进程能加锁成功,其他进程再尝试加锁时会阻塞,等同于我们常用的写锁

LOCK_NB :不阻塞标记。如果其他进程已加锁成功,自己去尝试加锁时就不再阻塞,而是直接返回错误

// 加锁
func (l *DirLock) Lock() error {
    f, err := os.Open(l.dir)
    if err != nil {
        return err
    }
    l.f = f

    err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
    if err != nil {
        return err
    }
    return nil
}

解锁的实现

核心代码是 syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)

LOCK_UN :解锁标记。如果自己已经加锁成功,可以用此标记去解锁

// 解锁
func (l *DirLock) Unlock() error {
    defer l.f.Close() // 关闭文件

    return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN) // LOCK_UN表解锁
}

实验

我们建立5个协程,每秒去尝试加锁一次,失败则1秒后重试,成功则持续2秒后解锁

核心代码如下

    // 5个协程,都尝试对目录加锁,加锁失败的就重试,加锁成功的2秒后释放
    for i := 0; i < 5; i++ {
        wg.Add(1)

        go func(num int) {
            dirLock := New(dir)
            ticker := time.NewTicker(time.Second) // 定时器每秒尝试1次
            for {
                select {
                case <-ticker.C:
                    {
                        err := dirLock.Lock() // 加锁尝试
                        if err != nil {
                            fmt.Printf("lock dir failed, goroutine num=%d, err=%s \n", num, err.Error())
                            continue
                        }
                        fmt.Println("lock dir succeed, goroutine num=", num)
                        goto end
                    }
                }
            }

            end:
            time.Sleep(time.Second*2)
            dirLock.Unlock() // 解锁
            wg.Done()
        }(i)
    }
    wg.Wait()

实验结果如下图

完整代码

package main
import ("fmt""os""sync""syscall""time"
)// 目录锁
type DirLock struct {dir 	string		// 目录的全路径名f   	*os.File	// 文件对象
}func New(dir string) *DirLock {return &DirLock{dir: dir,}
}// 加锁
func (l *DirLock) Lock() error {f, err := os.Open(l.dir)if err != nil {return err}l.f = ferr = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)if err != nil {return err}return nil
}// 释放锁
func (l *DirLock) Unlock() error {defer l.f.Close() // 其实不执行Close()也会释放目录锁return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)
}func main() {dir, _ := os.Getwd()wg := sync.WaitGroup{}// 5个协程,都尝试对目录加锁,加锁失败的就重试,加锁成功的2秒后释放for i := 0; i < 5; i++ {wg.Add(1)go func(num int) {dirLock := New(dir)ticker := time.NewTicker(time.Second) // 定时器每秒尝试1次for {select {case <-ticker.C:{err := dirLock.Lock() // 加锁尝试if err != nil {fmt.Printf("lock dir failed, goroutine num=%d, err=%s \n", num, err.Error())continue}fmt.Println("lock dir succeed, goroutine num=", num)goto end}}}end:time.Sleep(time.Second*2)dirLock.Unlock() // 解锁wg.Done()}(i)}wg.Wait()
}
http://www.hengruixuexiao.com/news/34551.html

相关文章:

  • 独立网店系统上海网络优化服务
  • 莱州网站制作百度竞价效果怎么样
  • 免费门户网站建设陕西seo快速排名
  • 网站结构优化的内容和方法全球网站排名查询
  • 如何腾讯云二级域名做网站重庆人社培训网
  • 做胃镜多少钱那好天津津门网站a网站流量统计分析
  • 大气企业网站源码苏州百度代理公司
  • 碑林微网站建设seo短视频发布页
  • wordpress教程 知乎郑州企业网站优化排名
  • 静态网站怎么做有效页网站收录查询网
  • 用什么做网站后台的全网营销策划公司
  • 网站设计美工要怎么做淘宝指数网站
  • 成都市建设部官方网站凡科小程序
  • 高端大气企业网站模板最新的域名网站
  • 香港企业注册信息查询谷歌seo靠谱吗
  • 专业单位网站开发注册网站查询
  • 做网站的业务分析引流推广的句子
  • 百度竞价排名收费标准seo分析seo诊断
  • 本地网站怎么做2021年近期舆情热点话题
  • 苏州建站公司谷歌排名优化入门教程
  • 济南it培训机构安阳seo
  • 58同城 招聘 找工作seo刷关键词排名优化
  • 中国互联网协会属于什么单位seo公司排行
  • 网站制作培训课程世界足球排名最新
  • 做婚纱摄影网站多少钱seo技术培训沈阳
  • 电子商务网站建设的特点seo优化培训
  • 北京免费做网站谷歌搜索引擎入口2021
  • 网站建设总体目标网络营销论文5000字
  • 怎么学做一件完整衣服网站优化网站结构一般包括
  • 建外贸网站 东莞seo教学免费课程霸屏