Go   发布时间:2022-04-09  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了利用golang并发下载股票数据(一)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

先贴上代码

//批量获取雅虎股票数据。
package main

import (
	"bufio"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"strconv"
	"Strings"
)

const (
	UA = "Golang Downloader from I@L_801_2@u.com"
)

func main() {
	runtime.GOMAXPROCS(runtime.Numcpu()) //设置cpu的核的数量,从而实现高并发
	c := make(chan bool)
	fh,ferr := os.Open("./shang.ini")   //上证里面的所有股票代码,每一行就是一个股票代码。
	if ferr != nil {
		return
	}
	defer fh.Close()
	inputread := bufio.NewReader(fh)

	for i := 0; i < 1162; i++ {
		input,_ := inputread.ReadString('\n')
		go getShangTickerTables(c,i,Strings.TrimSpace(input))
	}

	<-c

	fmt.Println("main ok")
}

func getShangTickerTables(c chan bool,n int,code String) {
	filename := "./data/sh/" + code + ".csv"
	f,err := os.OpenFile(filename,os.O_CREATE,0666) //其实这里的 O_RDWR应该是 O_RDWR|O_CREATE,也就是文件不存在的情况下就建一个文件,但是因为windows下还有BUG,如果使用这个O_CREATE,就会直接清空文件,所以这里就不用了这个标志,你自己事先建立好文件。
	if err != nil {
		panic(err)
	}
	stat,err := f.Stat() //获取文件状态
	if err != nil {
		panic(err)
	}
	defer f.Close()
	urls := "http://table.finance.yahoo.com/table.csv?s=" + code + ".ss"
	var req http.request
	req.Method = "GET"
	req.Close = true
	req.URL,err = url.Parse(urls)

	if err != nil {
		panic(err)
	}
	header := http.Header{}
	header.Set("Range","bytes="+strconv.Itoa(int(stat.Size()))+"-")
	header.Set("User-Agent",UA)
	req.Header = header
	resp,err := http.DefaultClient.Do(&req)
	if err != nil {
		panic(err)
	}

	io.Copy(f,resp.body)

	if n == 1161 {
		c <- true
	}
	defer resp.body.Close()
}

上面的代码存在2个严重的问题

1.不管在windows还是在linux下执行都会出错。

以linux为例讲,最开始是错误如下:

runtime/cgo: pthread_create Failed: resource temporarily unavailable
SIGABRT: abort
PC=0xca2424

goroutIne 1 [chan receive]:
main.main()
	/root/go/src/i@L_801_2@u/gettrackers/gettrackers.go:35 +0x13d

goroutIne 2 [syscall]:

goroutIne 4 [SELEct]:
net/http.(*Transport).getConn(0x18475120,0x1850b8a0,0x0,...)
	/usr/local/go/src/pkg/net/http/transport.go:407 +0x1ef
net/http.(*Transport).RoundTrip(0x18475120,0x18507e00,0x5,...)
	/usr/local/go/src/pkg/net/http/transport.go:181 +0x260
net/http.send(0x18507e00,0x184629c0,0x18475120,...)
	/usr/local/go/src/pkg/net/http/client.go:166 +0x2b8
net/http.(*Client).send(0x82e2240,0x34,0x18512058,0xb730ef40,...)
	/usr/local/go/src/pkg/net/http/client.go:100 +0xa5
net/http.(*Client).doFollowingRedirects(0x82e2240,0x821244c,...)
	/usr/local/go/src/pkg/net/http/client.go:282 +0x4d0
net/http.(*Client).Do(0x82e2240,0xa,...)
	/usr/local/go/src/pkg/net/http/client.go:129 +0x7b
main.getShangTickerTables(0x18466270,0x18400418,0x6)
	/root/go/src/i@L_801_2@u/gettrackers/gettrackers.go:64 +0x2a7
created by main.main
	/root/go/src/i@L_801_2@u/gettrackers/gettrackers.go:32 +0x117

goroutIne 5 [SELEct]:
net/http.(*Transport).getConn(0x18475120,0x1850b220,0x18c43150,...)
	/usr/local/go/src/pkg/net/http/transport.go:181 +0x260
net/http.send(0x18c43150,0x18ae6ec8,0xb730df40,0x1,0x18400428,0x6)
	/root/go/src/i@L_801_2@u/gettrackers/gettrackers.go:64 +0x2a7
created by main.main
	/root/go/src/i@L_801_2@u/gettrackers/gettrackers.go:32 +0x117

runtime/cgo: pthread_create Failed: resource temporarily unavailable
google了一下是DNS查询的问题,vi /etc/hosts,加入
67.195.146.181	table.finance.yahoo.com
即可解决上面的问题

2.根本没有按着预期请求完所有的数据

即,然我循环了1161次,预期是调用查询接口1162次,然后写入数据,但是并没有执行完1162次,实际只执行了100多次,因为其文件都是为空。

鄙人分析,是goroutIne的运行机制有关。参《Go语言编程》前言《并发与分布式》部分,原话如下:“Go语言在语言级别支持协程,叫goroutIne。Go语言标准库提供的所有系统调用(syscall)操作,当然也包括所有的同步IO操作,都会出让cpu给其它的goroutIne”,由此可见外层循环完了1162次,产生了1162个goroutIne,这些goroutIne有go语言的引擎负责自己调度执行,假设第1162个goroutIne被较早的调度,此时chAnnel就会被置为true,此时main就执行完了。如果是这种情况,那么

os.OpenFile(filename,0666)

可能就执行不了1162次,那么就不能创建1162个文件。但是运行显示的确产生了1162个文件。说明goroutIne的调度还是有顺序的。但是在执行每个goroutIne(即getShangTickerTables函数)时,由于有网络操作,所以此时会出让cpu给其它的goroutIne。由于网络IO比较费时,所以才会出现上面的情况,每个goroutIne都执行了一部分,然后由于网络IO被切换,chAnnel写入true,实际上每个

大佬总结

以上是大佬教程为你收集整理的利用golang并发下载股票数据(一)全部内容,希望文章能够帮你解决利用golang并发下载股票数据(一)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。