利用 channel (管道) 技术多线程下载图片.
package main import ( "io/ioutil" "log" "net/http" "os" "regexp" //"strconv" "strings" "sync" ) var urlist = [...]string{"http://stock.591hx.com/article/2014-12-03/0000850005s.shtml"} var album chan string var w sync.WaitGroup var dir string func main() { dir = "tmp_chenjo/" err := os.Mkdir(dir, 0777) if err != nil { isexist := os.IsExist(err) log.Println(isexist) } album = make(chan string, 200) for _, v := range urlist { w.Add(1) go GetAlbum(v) w.Wait() } } func GetAlbum(url string) { data := GetUrl(url) body := string(data) //<img src="http://stock.591hx.com/images/hnimg/201412/03/64/13418266510200941552.jpg" alt="" /></p> part := regexp.MustCompile(`<img src="(.*)" alt="" />`) match := part.FindAllStringSubmatch(body, -1) for _, v := range match { if m, _ := regexp.MatchString(`.*/hnimg/201412/03/.*\.jpg`, v[1]); !m { continue } //println(v[1]) album <- v[1] w.Add(1) go GetItem() } w.Done() } func GetItem() { url := <-album println(url) defer func() { ret := recover() if ret != nil { log.Println(ret) w.Done() } else { w.Done() } }() //data := GetUrl(url) //if len(data) > 10 { //body := string(data) //part := regexp.MustCompile(`bigimgsrc="(.*)"`) //match := part.FindAllStringSubmatch(body, -1) //for _, v := range match { str := strings.Split(url, "/") length := len(str) source := GetUrl(url) name := str[length-1] file, err := os.Create(dir + name) if err != nil { panic(err) } size, err := file.Write(source) defer file.Close() if err != nil { panic(err) } log.Println(size) //} //} } func GetUrl(url string) []byte { ret, err := http.Get(url) if err != nil { log.Println(url) status := map[string]string{} status["status"] = "400" status["url"] = url panic(status) } body := ret.Body data, _ := ioutil.ReadAll(body) return data }
console output:
G:/share/Golang/Golang.exe [G:/share/Golang]
2015/01/18 21:54:29 true
http://stock.591hx.com/images/hnimg/201412/03/64/13418266510200941552.jpg
http://stock.591hx.com/images/hnimg/201412/03/7/10886141709285175583.jpg
http://stock.591hx.com/images/hnimg/201412/03/0/5391574706574741364.jpg
http://stock.591hx.com/images/hnimg/201412/03/1/5405780767459854941.jpg
http://stock.591hx.com/images/hnimg/201412/03/16/13722698761317688276.jpg
http://stock.591hx.com/images/hnimg/201412/03/7/16853951343108680551.jpg
http://stock.591hx.com/images/hnimg/201412/03/50/17680852843413447062.jpg
http://stock.591hx.com/images/hnimg/201412/03/34/14366548421421579970.jpg
http://stock.591hx.com/images/hnimg/201412/03/4/17141924098089490820.jpg
2015/01/18 21:54:30 29968
2015/01/18 21:54:30 28697
2015/01/18 21:54:30 51586
2015/01/18 21:54:30 53031
2015/01/18 21:54:30 31234
2015/01/18 21:54:31 47618
2015/01/18 21:54:31 54649
2015/01/18 21:54:31 40422
2015/01/18 21:54:31 155527
成功: 进程退出代码 0.
相关推荐
Channel类似于管道,允许数据在并发组件之间流动,确保数据在正确的时间传递到正确的协程,同时避免了数据竞争和其他并发问题。 ### Channel的概念与语法 1. **概念**:Channel是一个先进先出(FIFO)的数据结构,...
总结来说,这个基于Golang的多用户通信系统利用了Golang的TCP套接字编程能力,通过Redis实现了高效的数据存储和检索,借助协程和管道实现了并发处理,从而能同时服务于多个用户。这样的设计保证了系统的高并发性和低...
1. **多线程下载文件**:通过创建多个goroutine并行下载大文件的不同部分,然后通过channel汇总结果,最终合成完整的文件。 2. **并发爬虫**:利用goroutine和channel构建高效的网络爬虫,实现网页的快速抓取和解析...
同步下载器与我们常见的多线程下载工具类似,它允许多个文件部分同时下载,以提高下载速度。godl就是这样一个工具,它利用Go语言的goroutine和channel特性,实现了高效的文件下载功能。 1. **Go语言基础** Go语言...
Channel则用于在goroutine之间安全地传递数据,它是类型化的管道,可以用来连接并发的函数。 Go语言的基础入门还包括了json数据的处理。Go语言的标准库中的encoding/json包,提供了对JSON数据的编码和解码功能。这...
例如,在Golang中,goroutines通过通道(Channel)实现数据的同步和传递,这种机制类似于管道。 4. **软件开发工具**:许多开发工具也利用管道原理,如Git的rebasing或merging流程,将多个提交顺序地应用到分支上。...
并发在Go中是一个核心特性,通过 goroutines 和 channels 实现,这使得编写能够充分利用多核处理器的高效程序变得相对简单。让我们深入探讨Go语言的并发特性。 **一、goroutines** goroutine 是Go语言中的轻量级...
### Go语言协程goroutine与管道channel教程 #### 一、引言 Go语言作为一种现代编程语言,以其简洁高效的语法和强大的并发模型受到广大开发者的喜爱。其中,协程(goroutine)和管道(channel)是Go语言实现高效并发...
- 并发支持:Go语言内置goroutine和channel,提供轻量级线程和通信机制,使得并发编程变得简单高效。 - 垃圾回收:自动内存管理,减轻程序员负担,提高程序安全性。 - 静态链接:默认情况下,Go程序会静态链接...
在Golang编程语言中,Gocurrency并发是其核心特性之一,它使得程序员能够编写高效、可扩展的多任务程序。Golang的并发模型基于CSP(Communicating Sequential Processes)理论,强调通过通信来共享内存,而不是通过...
在Go语言中,goroutine是一种轻量级线程,由语言本身支持,可以并发运行,而channel则是goroutine之间通信的桥梁,允许数据在不同的goroutine之间安全地传递。Go-ChanBroker利用这两个特性构建了一个类似Kafka的消息...
Goroutine是轻量级线程,而channel则可以被看作是goroutine之间的通信管道。在服务器端编程中,我们可能会创建多个goroutine来处理不同的任务或连接,而插槽可能是指分配给这些goroutine的特定工作区域或通信接口。 ...
在本项目中,我们将探讨如何利用Go语言构建一个聊天室,特别是其内置的高并发特性——goroutine和管道(channel)。 Goroutine是Go语言中的轻量级线程,它们比操作系统线程更轻便、更高效,因为它们由Go运行时管理...
这个库提供了一个简单的无锁实现,意味着它不依赖于Go的互斥锁(mutex)来保证数据的一致性,而是利用原子操作来确保在多线程环境下的安全性。无锁实现通常比使用锁的实现具有更低的延迟和更高的吞吐量,这对于高...
在Golang中,并发是其独特特性之一,它利用了Go协程(Goroutines)和通道(Channels)来实现高效的并行执行。本教程将深入探讨Go语言中的并发编程,帮助你理解如何利用这些工具来提升程序性能。 1. **Go协程...
这个例子展示了如何利用channel在并发执行的多个函数之间进行结果的汇总,体现了Go语言在并发编程方面的便利性。在实际的软件开发中,channel的使用场景非常广泛,比如在分布式系统中,可以用来实现服务之间的通信,...
在Go语言中,`channel`是并发编程的核心组成部分,它提供了一种安全地在多个goroutine(轻量级线程)之间传递数据的方式,从而实现了多核并行化运行。 在Go语言中,通过`channel`实现多核并行化运行的方法主要基于...
- **高效**:Go语言内置了并发支持,通过goroutine和channel机制简化了多线程编程的复杂度。 - **跨平台**:Go语言可以轻松地编译为不同操作系统(如Linux、Windows等)下的二进制文件,实现跨平台部署。 - **...
Channel是Go中用于goroutine间通信的管道,它具有以下特点: 1. 支持发送和接收数据。 2. 保证操作的同步性,发送和接收操作会阻塞goroutine,直到另一方准备好进行操作。 3. 可以是无缓冲的,也可以是有缓冲的。 ...