在Go语言中,程序的并发操作是通过通道(channel)来实现的。通道是用来传递数据的一种特殊类型,它可以在goroutine之间进行数据交换和通信。然而,如果在程序中使用单通道进行工作,并在引入新通道时没有正确处理,就有可能导致死锁现象的发生。本文将由php小编小新为大家详细解释Go程序中单通道工作和死锁问题,以及如何避免死锁的发生。
问题内容
我是Go通道的新手,我正在尝试通过构建模拟内核并通过通道处理交互来学习Go通道。此示例程序的目标是让多个进程 (2) 使用单通道同时向内核发送内存分配请求,其他进程发送释放内存请求 使用单个但不同的通道到内核。
+-------------+
+------------------+ | |
-> Alloc. Mem. Ch. |-->| Kernel |
| Process A | | Realse Mem. Ch. |登录后复制
如果我只有分配请求,程序就可以工作,一旦我引入释放请求,程序就会陷入死锁。
请注意,进程在发送分配请求时也会创建一个回复队列,但是,这在上图中没有显示,因为它不是问题的一部分。
完整的程序如下:
package main
import (
"fmt"
// "log"
"time"
)
const (
_ float64 = iota
LowPrio
MedPrio
HghPrio
)
// Kernel type to communicate between processes and memory resources
type Kernel struct {
reqMemCh chan chan int
rlsMemCh chan int
}
func (k *Kernel) Init() {
k.reqMemCh = make(chan chan int, 2)
k.rlsMemCh = make(chan int, 2)
go k.AllocMem()
go k.RlsMem()
}
// Fetch memory on process request
func (k *Kernel) GetReqMemCh() chan chan int {
return k.reqMemCh
}
func (k *Kernel) GetRlsMemCh() chan int {
return k.rlsMemCh
}
func (k *Kernel) AllocMem() {
// loop over the items (process reply channels) received over
// the request channel
for pCh := range k.GetReqMemCh() {
// for now think 0 is the available index
// send this as a reply to the exclusive process reply channel
pCh 登录后复制
异常情况如下:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.Proc.RlsMem(...)
main.go:100
main.main()
main.go:119 +0xc5
goroutine 6 [chan receive]:
main.(*Kernel).AllocMem(0x0?)
main.go:41 +0x5e
created by main.(*Kernel).Init in goroutine 1
main.go:25 +0xc5
exit status 2
登录后复制
任何帮助将不胜感激。
干杯,
DD。
解决方法
作为英国人评论,您有一个缓冲通道已达到其容量,但没有任何内容可供读取。
根据语言之旅 (1 2),发送和接收块,直到另一方准备好。虽然缓冲通道在这里提供了一些宽容,但一旦缓冲区已满,行为是相同的。
可以通过添加 k.rlsMemCh
的使用者来解决此问题。如果您没有为此计划任何操作,请删除该通道或暂时使用逻辑将其耗尽。
func (k *Kernel) Init() {
k.reqMemCh = make(chan chan int, 2)
k.rlsMemCh = make(chan int, 2)
go k.AllocMem()
go k.RlsMem()
}
func (k *Kernel) AllocMem() {
for pCh := range k.GetReqMemCh() {
pCh
登录后复制
排水可能如下所示:
func (k *Kernel) RlsMem() {
for {
登录后复制
以上就是Go 程序使用单通道工作,并在引入新通道时陷入死锁的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!