Go - 尝试创建超过一定数量的goroutine时出现分段违规

时间:2017-09-24 03:06:00

标签: multithreading go concurrency goroutine

我正试图在Go中强调测试一个http客户端。

首先,我只是尝试为10次迭代运行10个并发请求。

这是我的客户代码:

// stress.go
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

func MakeRequest(url string, ch chan<- string) {
    start := time.Now()
    resp, _ := http.Get(url)

    secs := time.Since(start).Seconds()
    body, _ := ioutil.ReadAll(resp.Body)
    ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
}

func main() {
    start := time.Now()
    goroutines := 10
    iterations := 10
    ch := make(chan string)
    url := "http://localhost:8000"
    for i := 0; i < iterations; i++ {
        for j := 0; j < goroutines; j++ {
            go MakeRequest(url, ch)
        }
    }
    for i := 0; i < goroutines*iterations; i++ {
        fmt.Println(<-ch)
    }

    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}

它适用于迭代和goroutines的这种组合。但是当goroutine和迭代的数量超过一定水平时,在我的情况下,对于单次迭代,当goroutines的数量超过634时,我收到此错误:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x11eb9f0]

goroutine 7099 [running]:
main.MakeRequest(0x1271897, 0x15, 0xc420074120)
        stress.go:16 +0xa0
                created by main.main
                        stress.go:28 +0xb2

根据this,可以轻松创建10000个goroutines。在我的情况下,我做错了什么?如何在给定的迭代次数下测试客户端可以同时进行的最大GET或POST请求数量?

1 个答案:

答案 0 :(得分:3)

您正在从http.Get和ioutil.ReadAll中丢弃错误,所以我并不感到惊讶,因为您获得了无指针取消引用;如果这不是一个有效的假设,那么你假设返回值是好的。服务器可能正在返回错误,因为您已超过服务器的最大吞吐量。

你还没有测试10次goroutines 10次迭代,你正在测试100个goroutines;并且在阅读完毕后,您并未关闭请求正文。最后,您可以获得多少吞吐量取决于服务器,服务器可用的资源量以及客户端可用的资源量;两者之间的竞争,因为您正在攻击localhost,客户端和服务器正在争夺相同的系统资源。

任何语言都没有静态性能特征;它取决于它运行的上下文。