用go语言写一个并发的快速排序

随风

快速排序,相信学过算法的各位大佬一定是再熟悉不过了。快速排序以其出色的性能,以及无需辅助空间,较容易实现而获得了极为广泛的使用。但随着CPU核数的日益增加,如何充分利用多核性能已经成为提高程序性能的又一大重要议题,因而在继续讨论iris框架的时候,我想先讨论一下go语言的杀手锏——并发编程。go语言对并发的原生支持,使其对于多核心利用极为有效。

在讨论并发编程之前,我们先来看看几个概念——进程,线程,协程。进程应该是我们最熟悉的。进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。由于进程需要分配系统资源,如内存之类的,故利用多进程来实现高并发显然是捉襟见肘,极为不实际。就在我们困厄的时候,线程应运而生,通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。当下推出的通用操作系统都引入了线程,以便进一步提高系统的并发性,并把它视为现代操作系统的一个重要指标。许多编程语言对线程的支持都很不错,如java。java有大量的线程操作库,如thread,继承之后重写run方法即可轻松启动一个线程。线程看似轻量,无往而不利,对提高并发量有着极为重要的作用。但它在面对秒杀等场景的时候,线程的缺陷也暴露出来,它始终是一个调度的基本单位,因而能够支持并发的数量也不会太高,普通的个人电脑难以实现百万线程,这时侯协程就应运而生。

协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。可见协程更加轻量,能够实现更高的并发。go语言的groutine正是利用了协程来实现。

那么协程之间如何通讯呢,不能通讯的协程其作用就大大削弱,go语言别出心裁的采用了Chanel实现,其实是一个阻塞队列,当然也可以是带有缓冲的非阻塞的,后面文章会详细讨论。

有了以上的基础知识,不难写出并发快排的代码

import “sync”

func MutiQuickSort(num []int){

lock.Add(1)

QuickSort(num, 0, len(num)-1)

lock.Wait()

}

var lock sync.WaitGroup

func QuickSort(num []int, low, high int) {

defer lock.Done()

if low >= high {

return }

i, j := low, high

key := num[low]

for i < j {

for j > i && num[j] >= key {

j } num[i] = num[j]

for i < j && num[i] < key {

i++ }

num[j] = num[i]

}

num[j] = key lock.Add(2)

go QuickSort(num, low, i-1)

go QuickSort(num, i+1, high)

}

可见用go语言处理并发优雅而方便,不愧为21世纪c语言。

部分来自百度百科,csdn

宇宙最快之go web框架——iris

随风

昨天兴致大发写了一篇go语言的文章,看到不少朋友对go语言还是很感兴趣的。今天兴致大发,决定再写一篇关于go web开发的文章。今天我想介绍的是宇宙最快之go web框架——iris。是不是有点夸张?我本人觉得确实有点夸张,不过iris框架的官方GitHub文档是这么写的,我也就不好反驳了,实际上iris框架的性能确实比spring boot高出很多,而且能满足树莓派等设备需求,轻量简洁,这大概也是go语言的特点吧。

做过后端的各位朋友肯定都知道,重造轮子是一件非常麻烦的事。我们固然可以从socket开始写起,但是这样的开发效率肯定是。。。(不用多说。。)其实java真正厉害的也许不是语言本身,而是附着在java上的众多框架,例如spring。有了这些脚手架,我们就可以站在前人的肩膀上走得更远。

iris的安装很容易,只需要go get -u github.com/kataras/iris,当然前提条件是安装了go编译器,如果不懂安装而对go语言感兴趣的话,也可以私信创万联公众号哦。

先来一段iris框架使用的简单demo

package main

import (
“github.com/kataras/iris”
“github.com/kataras/iris/context”
)

func main() {
app := iris.New()
app.Get(“/”, func(ctx context.Context){

ctx.HTML(“<h1>Welcome</h1>”)

})
app.Run(iris.Addr(“:8080”))
}

将其复制后保存到记事本,然后命名为main.go,打开命令行。go build main.go,打开浏览器输入127.0.0.1:8080/即可以看到welcome显示在浏览器上。是不是感觉很简单,很想尝试一下,那就赶快动手试试吧。

事实上iris为我们包装了路由处理以及完整的mvc框架支持,以及令人兴奋的中间件处理,考试要紧,今天我们就聊到这吧,下期再见。

go语言,未来的新选择

随风

做了一段时间的后端,有苦也有喜悦。在创万联的实战之中使我认识了一种全新的,令人喜悦而又忧虑的新语言——go语言。

go语言的哲学是少即是多。这是go的信条,这与java严密的逻辑体系有所不同。go语言没有泛型,没有类层次,在现代语言中显得有点特立独行。go语言奉行独特的组合思想,你走起来是鸭子你就是鸭子的思想使得go语言具有了独特的灵活。

go语言天生高并发,go语言创建一个协程极度简单。只需要go 函数即可。在多核心时代,这种设计无疑给编程人员带来了很大的方便。利用Chanel 进行消息传递避开了传统多线程互斥锁等操作,尽管不能完全消除,但至少使得高并发编程更加优雅。

go的面向对象编程其实是容易的,它使得类的神秘性不再存在,this指针被暴露眼前,多态虚函数等晦涩概念也无需深究。

当然go的缺点也显而易见,go的生态相对于java是那么的缺乏,以至于构建后端很多时候不得不重造轮子。但相信以后或许这种情况会得到改善,使得我们在写后端时候多一种选择。