Go语言实现线程安全访问队列

这个例子用Go语言的包”container/list”实现一个线程安全访问的队列。其中不少细节耐人寻味,做出它则是花费了不少精力,找不到样例啊!

Go语言的许多优点自不必说,然而从C/C++程序角度看,语言的语法也好,程序的实现方式也好,看起来总有点怪怪的感觉。

在这个程序的基础上,是很容易实现一个线程安全访问的堆栈的。

Go语言程序:

// structlist project main.go
package main

import (
    "container/list"
    "fmt"
    "sync"
)

const N int = 10

type QueueNode struct {
    figure  int
    digits1 [N]int
    digits2 [N]int
    sflag   bool

    data *list.List
}

var lock sync.Mutex

func newQueue() *QueueNode {
    q := new(QueueNode)
    q.data = list.New()
    return q
}

func (q *QueueNode) push(v interface{}) {
    defer lock.Unlock()
    lock.Lock()
    q.data.PushFront(v)
}

func (q *QueueNode) dump() {
    for iter := q.data.Back(); iter != nil; iter = iter.Prev() {
        fmt.Println("item:", iter.Value)
    }
}

func (q *QueueNode) pop() interface{} {
    defer lock.Unlock()
    lock.Lock()
    iter := q.data.Back()
    v := iter.Value
    q.data.Remove(iter)
    return v
}

func main() {
    var n QueueNode

    n.figure = 1
    n.digits1[0] = 1
    n.digits2[0] = 1
    n.sflag = true

    n2 := n
    n2.digits1[n2.figure] = 2
    n2.digits2[n2.figure] = 2
    n2.figure++
    n2.sflag = false

    n3 := n2
    n3.digits1[n2.figure] = 3
    n3.digits2[n2.figure] = 4
    n3.figure++

    q := newQueue()
    q.push(n)
    q.push(n2)
    q.push(n3)

    q.dump()

    fmt.Printf("\nlen=%d\n\n", q.data.Len())

    for q.data.Len() > 0 {
        x := q.pop().(QueueNode)
        output_node(&x)
    }

}

func output_node(n *QueueNode) {
    fmt.Printf("Figure =%d\n", n.figure)

    fmt.Printf("Array1: ")
    for i := n.figure - 1; i >= 0; i-- {
        fmt.Printf("%d ", n.digits1[i])
    }
    fmt.Println("")

    fmt.Printf("Array2: ")
    for i := n.figure - 1; i >= 0; i-- {
        fmt.Printf("%d ", n.digits2[i])
    }
    fmt.Println("")

    if n.sflag {
        fmt.Printf("SFlag=true\n")
    } else {
        fmt.Printf("SFlag=false\n")
    }

    fmt.Println("")
}

程序运行结果:

item: {1 [1 0 0 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0 0 0] true }
item: {2 [1 2 0 0 0 0 0 0 0 0] [1 2 0 0 0 0 0 0 0 0] false }
item: {3 [1 2 3 0 0 0 0 0 0 0] [1 2 4 0 0 0 0 0 0 0] false }

len=3

Figure =1
Array1: 1
Array2: 1
SFlag=true

Figure =2
Array1: 2 1
Array2: 2 1
SFlag=false

Figure =3
Array1: 3 2 1
Array2: 4 2 1
SFlag=false

程序说明:

1.接口类型转结构类型,花费了好多时间,其做法堪称一绝,见79行。

2.全局变量lock是队列访问锁。

3.队列使用来资源锁,设计成线程安全访问的。

4.程序中并没有使用goroutine,如果需要可以使用类似这样的代码”go func() { q.push(n) }()”

Original: https://www.cnblogs.com/tigerisland/p/7563544.html
Author: 海岛Blog
Title: Go语言实现线程安全访问队列

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535768/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • golang 标准库template的代码生成

    最近,随着 antd Pro v5 的升级,将项目进行了升级,现在生成的都是 ts 代码。这个项目的自动生成代码都是基于 golang 的标准库 template 的,所以这篇博客…

    Go语言 2023年5月25日
    039
  • Go语言之Goroutine与信道、异常处理

    一、Goroutine Go 协程可以看做成一个轻量级的线程,Go 协程相比于线程的优势: Goroutine 的成本更低大小只有 2 kb 左右,线程有几个兆。 Goroutin…

    Go语言 2023年5月25日
    053
  • 踩了个DNS解析的坑,但我还是没想通

    hello大家好,我是小楼。 最近踩了个DNS解析的小坑,虽然问题解决了,但排查过程比较曲折,最后还是有一点没有想通,整个过程分享给大家。 背景 最近负责的服务要置换机器。置换机器…

    Go语言 2023年5月25日
    0102
  • [grpc快速入门] 一 grpc生成与调用

    下载通用编译器 地址:https://github.com/protocolbuffers/protobuf/releases选择对应的版本,解压后将文件夹下bin目录配置到环境变…

    Go语言 2023年5月25日
    074
  • 浅谈MatrixOne如何用Go语言设计与实现高性能哈希表

    目录 MatrixOne数据库是什么? 哈希表数据结构基础 哈希表基本设计与对性能的影响 碰撞处理 链地址法 开放寻址法 Max load factor Growth factor…

    Go语言 2023年5月25日
    051
  • Go语言:包管理基础知识

    起因是,遇到一个问题: 经查阅资料,很可能跟包管理有关,之前有了解过忘了就再学一遍顺便解决问题。 学习资料: GO111MODULE 是个啥? – 知乎 (zhihu….

    Go语言 2023年5月25日
    055
  • Go语言之数组与切片基础

    数组是同一类型元素的集合,可以放多个值,但是类型一致,内存中连续存储 Go 语言中不允许混合不同类型的元素,而且数组的大小,在定义阶段就确定了,不能更改 1、数组的定义 // 定义…

    Go语言 2023年5月25日
    062
  • GO语言 文件操作实例

    package main import ( "bufio" "fmt" "io/ioutil" "os&quo…

    Go语言 2023年5月29日
    045
  • 大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14

    众所周知,Go lang的作用域相对严格,数据之间的通信往往要依靠参数的传递,但如果想在多个协程任务中间做数据通信,就需要通道(channel)的参与,我们可以把数据封装成一个对象…

    Go语言 2023年5月25日
    076
  • 读 Go 源码,可以试试这个工具

    原文链接: 读 Go 源码,可以试试这个工具 编程发展至今,从面向过程到面向对象,再到现在的面向框架。写代码变成了一件越来越容易的事情。 学习基础语法,看看框架文档,几天时间搞出一…

    Go语言 2023年5月25日
    042
  • Golang – 关于 proto 文件的一点小思考

    ProtoBuf 是什么? ProtoBuf 是一套接口描述语言(IDL),通俗的讲是一种数据表达方式,也可以称为数据交换格式。 我们常用的数据格式有 JSON 和 XML,为什么…

    Go语言 2023年5月25日
    054
  • golang多版本管理工具

    前言 以往我安装 go环境都是去网站上下载对应文件,然后本地解压。每次发布新版本都这样做太麻烦了,所以我在寻找多版本管理工具。 [En] It’s too troubl…

    Go语言 2023年5月25日
    054
  • 流量管制-令牌桶与漏桶

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Go语言 2023年5月25日
    052
  • Goland的那些实用技巧

    1、 自定义结构体tag 2、go mod tidy / download失败 解决办法:设置goproxy 3、取消/打开代码折叠 4、左侧project栏总是展示当前打开文件的…

    Go语言 2023年5月25日
    064
  • Sentinel-Go 源码系列(二)|初始化流程和责任链设计模式

    上节中我们知道了 Sentinel-Go 大概能做什么事情,最简单的例子如何跑起来 其实我早就写好了本系列的第二篇,但迟迟没有发布,感觉光初始化流程显得有些单一,于是又补充了责任链…

    Go语言 2023年5月25日
    054
  • Go内存逃逸分析

    Go的内存逃逸及逃逸分析 Go的内存逃逸 分析内存逃逸之前要搞清楚一件事 我们编写的程序中的 函数和 局部变量默认是存放在栈上的(补充一点堆上存储的数据的指针 是存放在栈上的 因为…

    Go语言 2023年5月25日
    041
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球