Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
goroutine阻塞和非阻塞使用_Go_Channel_Goroutine - Fatal编程技术网

goroutine阻塞和非阻塞使用

goroutine阻塞和非阻塞使用,go,channel,goroutine,Go,Channel,Goroutine,我正在努力理解日常工作是如何进行的。下面是一些代码: //parallelSum.go func sum(a []int, c chan<- int, func_id string) { sum := 0 for _, n := range a { sum += n } log.Printf("func_id %v is DONE!", func_id) c <- sum } func main() { ELEM_

我正在努力理解日常工作是如何进行的。下面是一些代码:

//parallelSum.go
func sum(a []int, c chan<- int, func_id string) {
    sum := 0
    for _, n := range a {
        sum += n
    }
    log.Printf("func_id %v is DONE!", func_id)
    c <- sum
}   
func main() {
    ELEM_COUNT := 10000000
    test_arr := make([]int, ELEM_COUNT)
    for i := 0; i < ELEM_COUNT; i++ {
        test_arr[i] = i * 2 
    }
    c1 := make(chan int)
    c2 := make(chan int)
    go sum(test_arr[:len(test_arr)/2], c1, "1")
    go sum(test_arr[len(test_arr)/2:], c2, "2")
    x := <-c1
    y := <-c2

    //x, y := <-c, <-c
    log.Printf("x= %v, y = %v, sum = %v", x, y, x+y)
}   
以下是1次运行的输出:

average time for iterSum = 0.27
average time for parallelSum = 0.29

所以,这里有几个问题。首先,在并发示例中,您的通道没有缓冲,这意味着接收端可能还需要彼此等待一段时间。其次,并发并不意味着并行。您确定这些线程实际上是并行运行的,而不是简单地调度在同一个OS线程上吗

也就是说,这里的主要问题是Python代码在每次迭代中都使用了
go-run
,这意味着记录的绝大多数“运行时”实际上是代码的编译(
go-run
编译并运行指定的文件,特别是在设计时,它不会缓存任何文件)。如果您想测试运行时,请使用,而不是您自己的拼凑版本。你会得到更准确的结果。例如,除了编译瓶颈之外,也无法确定Python代码本身引入了多少瓶颈


哦,您应该改掉使用函数引用参数作为“返回”值的方法的习惯。Go支持多个返回,因此C风格的就地修改参数通常被认为是一种反模式,除非有真正令人信服的理由这样做。

因此,这里有几个问题。首先,在并发示例中,您的通道没有缓冲,这意味着接收端可能还需要彼此等待一段时间。其次,并发并不意味着并行。您确定这些线程实际上是并行运行的,而不是简单地调度在同一个OS线程上吗

也就是说,这里的主要问题是Python代码在每次迭代中都使用了
go-run
,这意味着记录的绝大多数“运行时”实际上是代码的编译(
go-run
编译并运行指定的文件,特别是在设计时,它不会缓存任何文件)。如果您想测试运行时,请使用,而不是您自己的拼凑版本。你会得到更准确的结果。例如,除了编译瓶颈之外,也无法确定Python代码本身引入了多少瓶颈


哦,您应该改掉使用函数引用参数作为“返回”值的方法的习惯。Go支持多个返回,因此C风格的就地修改参数通常被认为是一种反模式,除非有令人信服的理由这样做。

“并行化不应该让事情更快吗?”也许。并发不是一个灵丹妙药,并发的影响很大程度上取决于操作环境(硬件、操作系统等)和正在执行的代码。“并行化不应该让事情变得更快吗?”也许。并发不是万能的,并发的影响很大程度上取决于操作环境(硬件、操作系统等)和正在执行的代码。我认为Python代码不会引入瓶颈。在unix上,它本质上被转换为
time
命令,仅此而已。但您无法实际证明这一点。Python的解释速度比Go慢,并且在Unix中使用
time
命令的精度远远低于Go运行时在基准测试期间使用的直接OS API调用。我认为Python代码不会引入瓶颈。在unix上,它本质上被转换为
time
命令,仅此而已。但您无法实际证明这一点。Python是解释型的,它天生比Go慢,并且在Unix中使用
time
命令远不如Go运行时在基准测试期间使用的直接OS-API调用精确。
iterCmd = 'go run iterSum.go'
parallelCmd = 'go run parallelSum.go'

runCount = 20


def analyzeCmd(cmd, runCount):
    runData = []
    print("running cmd (%s) for (%s) times" % (cmd, runCount))
    for i in range(runCount):
    ┆   start_time = time.time()
    ┆   cmd_out = subprocess.check_call(shlex.split(cmd))
        run_time = time.time() - start_time
    ┆   curr_data = {'iteration': i, 'run_time' : run_time}
    ┆   runData.append(curr_data)

    return runData

iterOut = analyzeCmd(iterCmd, runCount)
parallelOut = analyzeCmd(parallelCmd, runCount)

print("iter cmd data -->")
print(iterOut)

with open('iterResults.json', 'w') as f:
    json.dump(iterOut, f)

print("parallel cmd data -->")
print(parallelOut)

with open('parallelResults.json', 'w') as f:
    json.dump(parallelOut, f)

avg = lambda results: sum(i['run_time'] for i in results) / len(results)
print("average time for iterSum = %3.2f" % (avg(iterOut)))
print("average time for parallelSum = %3.2f" % (avg(parallelOut)))
average time for iterSum = 0.27
average time for parallelSum = 0.29