《go语言程序设计》学习(九)

一,线程安全的类

package safeslice

type safeSlice chan commandData

type commandData struct {
    action  commandAction
    index   int
    item    interface{}
    result  chan<- interface{}
    data    chan<- []interface{}
    updater UpdateFunc
}

type commandAction int

const (
    insert commandAction = iota
    remove
    at
    update
    end
    length
)

type UpdateFunc func(interface{}) interface{}

type SafeSlice interface {
    Append(interface{})     // Append the given item to the slice
    At(int) interface{}     // Return the item at the given index position
    Close() []interface{}   // Close the channel and return the slice
    Delete(int)             // Delete the item at the given index position
    Len() int               // Return the number of items in the slice
    Update(int, UpdateFunc) // Update the item at the given index position
}

func New() SafeSlice {
    slice := make(safeSlice)
    go slice.run()
    return slice
}

func (slice safeSlice) run() {
    list := make([]interface{}, 0)
    for command := range slice {
        switch command.action {
        case insert:
            list = append(list, command.item)
        case remove: // potentially expensive for long lists
            if 0 <= command.index && command.index < len(list) {
                list = append(list[:command.index],
                    list[command.index+1:]...)
            }
        case at:
            if 0 <= command.index && command.index < len(list) {
                command.result <- list[command.index]
            } else {
                command.result <- nil
            }
        case length:
            command.result <- len(list)
        case update:
            if 0 <= command.index && command.index < len(list) {
                list[command.index] = command.updater(list[command.index])
            }
        case end:
            close(slice)
            command.data <- list
        }
    }
}

func (slice safeSlice) Append(item interface{}) {
    slice <- commandData{action: insert, item: item}
}

func (slice safeSlice) Delete(index int) {
    slice <- commandData{action: remove, index: index}
}

func (slice safeSlice) At(index int) interface{} {
    reply := make(chan interface{})
    slice <- commandData{at, index, nil, reply, nil, nil}
    return <-reply
}

func (slice safeSlice) Len() int {
    reply := make(chan interface{})
    slice <- commandData{action: length, result: reply}
    return (<-reply).(int)
}

// If the updater calls a safeSlice method we will get deadlock!
func (slice safeSlice) Update(index int, updater UpdateFunc) {
    slice <- commandData{action: update, index: index, updater: updater}
}

func (slice safeSlice) Close() []interface{} {
    reply := make(chan []interface{})
    slice <- commandData{action: end, data: reply}
    return <-reply
}

这是一个线程安全的slice,表面上看,看不到任何锁或者互斥量等任何操作来实现线程安全。

实际上,着应该说,说一个披着slice外衣的actor。。

整个实现说这样:启动一个gorountin,并给它一个channel,当需要操作这个slice点时候,就把希望操作的信息封装进command这个struct内,然后把整个struct打包,从这个channel发送到gorountin,然后这个“slice”有序的从gorountin读取到这个command,就按照command的操作信息,把command操作执行。

如果gorountin没有缓冲区,那么所有多操作都是阻塞的,也就是说,如果1-5这5个线程按顺序的都要操作这个slice,那么,在第一个请求执行完之前,其他线程的请求都时挂起的,直到第一个执行完,按顺序执行第二个。

时间: 2024-10-12 19:59:36

《go语言程序设计》学习(九)的相关文章

C语言程序设计学习心得

一,思维导图 二,语法认识 1,if-else的用法 if (条件一) { 语句一; } else { 语句二; } 问题:else与if的匹配关系不明确,导致程序异常. 解决方法:牢记else与离其最近的一个if配对,不与其他的if连用,并规范代码书写格式,使其看起来跟加清晰明了. 2,while语句的用法 while (循环条件) { 循环语句; } 注意事项:while比较好用,基本上所有的循环结构都能用while写. 3,for语句的用法 for(表达式1; 表达式2; 表达式3) {

中国大学MOOC-翁恺-C语言程序设计习题集

Technorati 标签: 中国大学MOOC-翁恺-C语言程序设计习题集,C 今年网易出了"中国大学MOOC",于是选了浙大翁恺老师的"C语言程序设计"学习,近期打算把自己在该课程中的PAT习题解答做一个记录,等自己编程能力提高后再来看现在写的代码哪里还有写的不好,可以改进的地方,达到反思的目的.   中国大学MOOC-翁恺-C语言程序设计习题集,布布扣,bubuko.com

C语言程序设计入门学习五步曲(转发)

笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的语法知识,而我们编写的程序或软件是要根据要解决问题的实际需要控制程序的流程,如果你没有深刻地理解C语言的语句的执行过程(或流程),你怎么会编写程序解决这些实际问题呢? 二.用C语言编程解决实际问题,所需要的不仅仅是C语言的编程知识,还需要相关的专业知识.例如,如果你不知道长方形的面积公式,即使C语言

初探swift语言的学习笔记九(OC与Swift混编)

swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. 先中简单的入手,先研究在同一个工程目录下混合使用的情况. 为了演示.先准备两个类 第一个是swift语言写的类,文件名为 act.swift import Foundation class Act : NSObject { func hasAct(tag:Int) -> String { swit

2018年秋季学期《c语言程序设计》学习总结

<c语言程序设计>第四周学习总结 <c语言程序设计>第五周学习总结 <c语言程序设计>第六周学习总结 <c语言程序设计>第七周学习总结 <c语言程序设计>第八周学习总结 <c语言程序设计>第九周学习总结 <c语言程序设计>第十周学习总结 <c语言程序设计>第十一周学习总结 <c语言程序设计>第十二周学习总结 <c语言程序设计>第十三周学习总结 原文地址:https://www.cnblo

《go语言程序设计》学习(一)

序言 2年前的这个时候认识到了golang,然后兴匆匆的去书店买了本书,go语言,云动力吧好像是,结果拿过来一开始,环境就设置不上,折腾了几天,然后就不了了之了. 1年前的这个时候,再次路过书店,看到了<go语言程序设计>这本书,按耐不住心痒痒,又买回来,结果看了两章,又头昏脑胀,没坚持下去. 前几天看很多人都在讨论golang,我就又去把书翻出来了,这次决定要再前进一步,争取把书看完. (一个拖延症的懒癌患者的内心,是咆哮的) 一,示例代码:gobook已下载 二,开发环境:go 1.4,v

C语言:C语言程序设计初步

.:.:第三章:c语言程序设计初步:.:. 第三章: C语言程序设计初步 C语言程序设计 本课介绍C语言程序设计的基本方法和基本的程序语句.从程序流程的角度来看,程序可以分为三种基本结构, 即顺序结构.分支结构.循环结构. 这三种基本结构可以组成所有的各种复杂程序.C语言提供了多种语句来实现这些程序结构. 本章介绍这些基本语句及其应用,使读者对C程序有一个初步的认识, 为后面各章的学习打下基础. C程序的语句 C程序的执行部分是由语句组成的. 程序的功能也是由执行语句实现的.C语句可分为以下五类

《Java语言程序设计》大作业报告 九宫格游戏

    <Java语言程序设计>大作业报告     中国石油大学(北京)2015 - 2016 学年第二学期     班级:_____计算机14-1_______ 姓名:_____  许 恺_________________ 学号:______2014011329___________     题意分析 程序首先需要九个可以移动的格子,大小相等,有字符串标示,其次要可以相应鼠标和键盘方向键的控制,可以自由移动,并且与此同时记录步数,最后在满足条件时弹出对话框并显示步数以及是否打破记录,关于打破

Linux 程序设计学习笔记----进程管理与程序开发(下)

转载请注明出处:http://blog.csdn.net/suool/article/details/38419983,谢谢! 进程管理及其控制 创建进程 fork()函数 函数说明具体参见:http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html 返回值:Upon successful completion, fork() shall return 0 to the child process and shall re

《VB语言程序设计(第3版)》总结

我之前因学习昆仑通态的组态软件MCGS,用并学习过VB,还买了一本书<VB语言程序设计(第3版)>.现在在某公司实习,最近接触老的项目,又要用到VB.我就又把那本书大体看了一遍,并对其进行了总结.之所以总结这个,主要是书太多了,想把那本书丢了,呵呵,但又得留下点东西吧. 下面一张图概括了VB的大部分基础知识点,看了这个图基本就不用看书了,哈哈. 我学习VB主要是在VB6.0的环境下学习的.下面介绍一下VB的一些基本语句. (1)声明语句 Dim score As Integer, temp A