我对围棋语言比较陌生。尽管我不希望如此,但我可能会用一个愚蠢的问题来打扰你。我先道歉,以防万一...
下面是我的示例:我定义了一个worker()函数,它作为一组并发Go例程从main()调用。输入和输出数据通过片类型[]int的输入和输出通道提供。在一种情况下,一切正常,在另一种情况下,结果有误。请参阅代码中的注释和代码下面的程序输出。
老实说,我看不出这两种代码变体之间的实际区别。我错过了什么?谢谢你的建议!
package main
import "fmt"
import "runtime"
func worker(x_ch <-chan []int, y_ch chan<- []int, wid int) {
for x := range x_ch {
y := x
fmt.Println(" worker", wid, "x:", x)
fmt.Println(" worker", wid, "y:", y)
y_ch <- y
}
}
func main() {
n_workers := runtime.NumCPU()
n_len := 4
n_jobs := 4
x := make([]int, n_len)
x_ch := make(chan []int, 10)
y_ch := make(chan []int, 10)
for j := 0; j < n_workers; j++ { go worker(x_ch, y_ch, j) }
for k := 0; k < n_jobs; k++ {
// variant 1: works!
x = []int{k, k, k, k}
// variant 2: doesn't work!
// for i := range x { x[i] = k }
fmt.Println("main x:", k, x)
x_ch <- x
}
close(x_ch)
for i := 0; i < n_jobs; i++ {
z := <- y_ch
fmt.Println(" main y:", i, z)
}
}
正确产出(变式1):
main x: 0 [0 0 0 0]
main x: 1 [1 1 1 1]
main x: 2 [2 2 2 2]
main x: 3 [3 3 3 3]
worker 3 x: [3 3 3 3]
worker 3 y: [3 3 3 3]
worker 2 x: [2 2 2 2]
worker 2 y: [2 2 2 2]
worker 1 x: [0 0 0 0]
worker 1 y: [0 0 0 0]
worker 0 x: [1 1 1 1]
worker 0 y: [1 1 1 1]
main y: 0 [3 3 3 3]
main y: 1 [2 2 2 2]
main y: 2 [0 0 0 0]
main y: 3 [1 1 1 1]
输出错误(变量2):
main x: 0 [0 0 0 0]
main x: 1 [1 1 1 1]
main x: 2 [2 2 2 2]
main x: 3 [3 3 3 3]
worker 3 x: [3 3 3 3]
worker 3 y: [3 3 3 3]
main y: 0 [3 3 3 3]
worker 0 x: [2 2 2 2]
worker 0 y: [3 3 3 3]
main y: 1 [3 3 3 3]
worker 1 x: [1 1 1 1]
worker 1 y: [3 3 3 3]
main y: 2 [3 3 3 3]
worker 2 x: [3 3 3 3]
worker 2 y: [3 3 3 3]
main y: 3 [3 3 3 3]
非常感谢你的解释,现在我知道问题出在哪里了。我添加了一些调试代码来输出指针地址,结果是(稍微重新格式化输出):
变式1:
main 0 x=[0 0 0 0] &x=0x1830e180 &x[0]=0x1830e1e0
main 1 x=[1 1 1 1] &x=0x1830e180 &x[0]=0x1830e230
main 2 x=[2 2 2 2] &x=0x1830e180 &x[0]=0x1830e270
main 3 x=[3 3 3 3] &x=0x1830e180 &x[0]=0x1830e2a0
worker 3 x=[3 3 3 3] &x=0x1830e1d0 &x[0]=0x1830e2a0
worker 3 y=[3 3 3 3] &y=0x1830e2e0 &y[0]=0x1830e2a0
main 0 y=[3 3 3 3] &y=0x1830e2d0 &y[0]=0x1830e2a0
worker 0 x=[0 0 0 0] &x=0x1830e1a0 &x[0]=0x1830e1e0
worker 0 y=[0 0 0 0] &y=0x1830e370 &y[0]=0x1830e1e0
main 1 y=[0 0 0 0] &y=0x1830e360 &y[0]=0x1830e1e0
worker 1 x=[1 1 1 1] &x=0x1830e1b0 &x[0]=0x1830e230
worker 1 y=[1 1 1 1] &y=0x1830e400 &y[0]=0x1830e230
main 2 y=[1 1 1 1] &y=0x1830e3f0 &y[0]=0x1830e230
worker 2 x=[2 2 2 2] &x=0x1830e1c0 &x[0]=0x1830e270
worker 2 y=[2 2 2 2] &y=0x1830e480 &y[0]=0x1830e270
main 3 y=[2 2 2 2] &y=0x1830e470 &y[0]=0x1830e270
变式2:
main 0 x=[0 0 0 0] &x=0x1830e180 &x[0]=0x1830e190
main 1 x=[1 1 1 1] &x=0x1830e180 &x[0]=0x1830e190
main 2 x=[2 2 2 2] &x=0x1830e180 &x[0]=0x1830e190
main 3 x=[3 3 3 3] &x=0x1830e180 &x[0]=0x1830e190
worker 3 x=[3 3 3 3] &x=0x1830e1d0 &x[0]=0x1830e190
worker 3 y=[3 3 3 3] &y=0x1830e2a0 &y[0]=0x1830e190
main 0 y=[3 3 3 3] &y=0x1830e290 &y[0]=0x1830e190
worker 0 x=[3 3 3 3] &x=0x1830e1a0 &x[0]=0x1830e190
worker 0 y=[3 3 3 3] &y=0x1830e330 &y[0]=0x1830e190
main 1 y=[3 3 3 3] &y=0x1830e320 &y[0]=0x1830e190
worker 1 x=[3 3 3 3] &x=0x1830e1b0 &x[0]=0x1830e190
worker 1 y=[3 3 3 3] &y=0x1830e3c0 &y[0]=0x1830e190
main 2 y=[3 3 3 3] &y=0x1830e3b0 &y[0]=0x1830e190
worker 2 x=[3 3 3 3] &x=0x1830e1c0 &x[0]=0x1830e190
worker 2 y=[3 3 3 3] &y=0x1830e440 &y[0]=0x1830e190
main 3 y=[3 3 3 3] &y=0x1830e430 &y[0]=0x1830e190
不同的是,在变体1中,您每次都发送不同的切片,而在变体2中,您每次都发送相同的切片(在循环的上面创建的切片)。在不创建新切片的情况下,您只是将同一切片的元素设置为不同的值,因此goroutine在查看切片时会看到切片中的任何值。在变体2中,
main
将始终看到[3 3 3]
,因为这是经过4次循环后的最终值。切片对象的值包含对基础元素的引用,而不是元素本身。这里对切片有一个很好的解释。
前面两节里我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是$h$和$w$(像素),那么它可以表示为一个$3\times h\times w$的多维数组。我们将大小为3的这一维称为通道(channel)维。本节我们将介绍含多个输入通道或多个输出通道的卷积核。 多输入通道 当输入数据含多个通道时
问题内容: 我想在Linux操作系统上的C程序内执行以下操作: 使用syscall(或2)创建PIPE 使用exec()执行新流程 将流程的STDIN连接到先前创建的管道。 将流程的输出连接到另一个PIPE。 这样做的目的是为了性能目的而避免访问任何驱动器。 我知道使用PIPE系统调用创建管道非常简单,我可以使用popen为输入或输出目的创建管道。 但是您将如何针对输入和输出执行此操作? 问题答案
问题内容: 本质上,我正在尝试替换: 为了避免使用硬盘驱动器,请在C ++中使用管道。这是我的代码: 我绝对可以确保上述字符串已正确初始化。但是,发生了两件事对我来说没有意义: (1)我正在执行的程序报告“输入文件为空”。由于我未使用“ <”调用程序,因此不应期望输入文件。相反,它应该期待键盘输入。此外,它应该阅读“ gulp_command”中包含的文本。 (2)程序的报告(通过标准输出提供)出
FAQs in section [15]: [15.1] 为什么应该用 <iostream> 而不是传统的 <cstdio>? [15.2] 当键入非法字符时,为何我的程序进入死循环? [15.3] 那个古怪的while (std::cin >> foo)语法如何工作? [15.4] 为什么我的输入处理会超过文件末尾? [15.5] 为什么我的程序在第一个循环后,会忽略输入请求呢? [15.6]
在我的应用程序中,我试图基于从服务方法返回的http状态值进行路由,其余的http状态将被路由到默认错误通道。但是这种默认映射不起作用,
输出 用print加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下: >>> print 'hello, world' print语句也可以跟上多个字符串,用逗号“,”隔开,就可以连成一串输出: >>> print 'The quick brown fox', 'jumps over', 'the lazy dog' The quick brown