英文:
Channel never dies although closed
问题
在下面的代码中,我试图将发送到inputs
通道的所有文件写入,并通过operationOutcomes
通道发送相应的响应。
main.go
package main
import(
lr "github.com/fabulousduck/librarian"
"fmt"
)
func main() {
writeOpCount := 100;
operationOutcomes, inputs := make(chan lr.WriteOpResponse), make(chan lr.WriteOp)
go lr.WriteC(inputs, operationOutcomes)
for i := 0; i < writeOpCount; i++ {
inputs <- lr.WriteOp{ Dest: `../exampleFiles/createdFiles/{i}.txt`, Content: `Invoice #{i}` }
}
close(inputs)
for i := 0; i < writeOpCount; i++ {
writeResult := <-operationOutcomes
fmt.Println("Response from write operation : ", writeResult.Msg, "err ", writeResult.Err, "bytes written : ", writeResult.BytesWritten)
}
close(operationOutcomes)
}
librarian.go
package librarian
import(
"os"
"fmt"
)
type WriteOp struct {
Dest, Content string
}
type WriteOpResponse struct {
Msg error
Err bool
BytesWritten int
}
func WriteC (inputChannel <-chan WriteOp, outputChannel chan<- WriteOpResponse) {
workOp := <-inputChannel
go writeWorker(workOp, outputChannel)
}
func writeWorker (job WriteOp, outGoing chan<- WriteOpResponse) {
file, err := os.OpenFile(job.Dest, os.O_RDWR, 0666)
if err != nil {
fmt.Println("err : ", err)
outGoing <- WriteOpResponse{ Msg: err, Err: true, BytesWritten: 0 }
}
bytesWritten , err := file.WriteString(job.Content)
if err != nil {
outGoing <- WriteOpResponse{ Msg: err, Err: true, BytesWritten: 0 }
}
outGoing <- WriteOpResponse{ Msg: nil, Err: false, BytesWritten: bytesWritten }
}
无论是否出现错误,这两种情况都会导致死锁,即使我在使用完它们后关闭了两个通道。
英文:
In the following code, i am trying to write all files that are sent to the inputs
channel and send a corresponding response over the operationOutcomes
channel
main.go
package main
import(
lr "github.com/fabulousduck/librarian"
"fmt"
)
func main() {
writeOpCount := 100;
operationOutcomes, inputs := make(chan lr.WriteOpResponse), make(chan lr.WriteOp)
go lr.WriteC(inputs, operationOutcomes)
for i := 0; i < writeOpCount; i++ {
inputs <- lr.WriteOp{ Dest: `../exampleFiles/createdFiles/{i}.txt`, Content: `Invoice #{i}` }
}
close(inputs)
for i := 0; i < writeOpCount; i++ {
writeResult := <-operationOutcomes
fmt.Println("Response from write operation : ", writeResult.Msg, "err ", writeResult.Err, "bytes written : ", writeResult.BytesWritten)
}
close(operationOutcomes)
}
librarian.go
package librarian
import(
"os"
"fmt"
)
type WriteOp struct {
Dest, Content string
}
type WriteOpResponse struct {
Msg error
Err bool
BytesWritten int
}
func WriteC (inputChannel <-chan WriteOp, outputChannel chan<- WriteOpResponse) {
workOp := <-inputChannel
go writeWorker(workOp, outputChannel)
}
func writeWorker (job WriteOp, outGoing chan<- WriteOpResponse) {
file, err := os.OpenFile(job.Dest, os.O_RDWR, 0666)
if err != nil {
fmt.Println("err : ", err)
outGoing <- WriteOpResponse{ Msg: err, Err: true, BytesWritten: 0 }
}
bytesWritten , err := file.WriteString(job.Content)
if err != nil {
outGoing <- WriteOpResponse{ Msg: err, Err: true, BytesWritten: 0 }
}
outGoing <- WriteOpResponse{ Msg: nil, Err: false, BytesWritten: bytesWritten }
}
This throws a deadlock in both cases when there is and isn't an error, even though i am closing both channels when i am done with them ?
答案1
得分: 1
你只读取了operationOutcomes
到writeOpCount
次数,即使在writeWorker
中,每次执行都可能导致在该通道上写入多达3条消息(没有错误情况会导致函数返回,因此它会继续处理)。由于它是无缓冲的并且停止被读取,所以在某个时刻,写入该通道的工作线程将无法再添加消息,从而永久锁定。
此外,由于你只调用了一次WriteC
且没有循环,它只会从inputs
中读取和处理一条消息。如果writeOpCount
大于1,则在第一次循环中尝试排队第二条消息时,它将永久锁定。
英文:
You only read from operationOutcomes
up to writeOpCount
times, even though in writeWorker
each execution can result in up to 3 messages being written on that channel (none of your error cases causes the function to return, to it continues processing). Because it's unbuffered and it stops being read, at some point the workers writing to it can no longer add messages and so lock forever.
Also, since you only call WriteC
once and it does not loop, it will only ever read and process one message from the inputs
. If writeOpCount
is > 1, then it will lock forever within the first loop when it tries to queue a second message.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论