提问人:baris 提问时间:7/26/2023 最后编辑:Peter Mortensenbaris 更新时间:7/28/2023 访问量:76
我应该把“mutex”放在哪里才能从 Go 的切片中删除元素?父结构还是子结构?
Where should I put `mutex` in order to delete an element from a slice in Go? The parent or child struct?
问:
假设我有两个结构,如下所示:
type Device struct {
Ports []*TCPPort
}
type TCPPort struct {
ID int
State bool
Device *Device
}
创建 a 时,将按如下方式追加:TCPPort
// Body of the `createTCPPort is intentionally left blank. Imagine it creates a port and returns it.`
func createTCPPort() *TCPPort {}
tcp := createTCPPort()
device.Ports = append(device.Ports, tcp)
在任何给定时间,都会请求删除其中一个 TCP 端口。我想从这个切片中删除/移除这个端口,在那里我通过设备附加了这些端口。港口。目前我猜这个操作是否按顺序进行并不重要。我很困惑我应该把和使用它的功能放在哪里,它们是 和 .Ports []*TCPPort
Mutex
lock
unlock
我应该像下面这样把它放在结构体中吗?Device
type Device struct {
portMutex sync.Mutex
Ports []*TCPPort
}
// And then remove the element as follows:?
func (d Device) removePortFromSlice(){
d.portMutex.Lock()
defer d.portMutex.Lock()
// Remove slice operation here
}
或
type TCPPort struct {
PortMutex sync.Mutex
ID int
State bool
Device *Device
}
func (tcp TCPPort) removeElementFromSlice() {
tcp.portMutex.Lock()
defer tcp.portMutex.Lock()
// Remove operation here
}
我应该将互斥锁放入父结构体还是子结构体中?Device
TCPPort
答:
0赞
TiGo
7/26/2023
#1
由于端口切片是设备结构上的一个字段,因此将互斥锁放在设备中以同步对该特定字段的访问是有意义的。
以下是有关使用互斥锁的建议:
type Device struct {
portMutex sync.Mutex
Ports []*TCPPort
}
func (d *Device) RemovePort(port *TCPPort) {
d.portMutex.Lock()
defer d.portMutex.Unlock()
// Find index of port to remove
index := -1
for i, p := range d.Ports {
if p == port {
index = i
break
}
}
// Remove from slice
if index != -1 {
d.Ports = append(d.Ports[:index], d.Ports[index+1:]...)
}
}
这将锁定对端口切片的访问,特别是在删除项目时。
将互斥锁放在 TCPPort 上效果不佳,因为即使每个 TCPPort 结构都将被锁定,Device 中的切片仍可由其他 goroutine 同时修改。 关键是同步对需要并发访问保护的共享数据结构的访问。
-3赞
Mohammad Safakhou
7/26/2023
#2
是的,可以使用互斥锁安全地处理对设备结构中端口切片的并发访问。将互斥锁放在设备结构中是一种合理的方法。
下面介绍如何修改设备结构并添加方法,以使用互斥锁安全地添加和删除 TCP 端口:
import "sync"
type Device struct {
Ports []*TCPPort
mu sync.Mutex // Mutex to protect access to Ports
}
type TCPPort struct {
ID int
State bool
Device *Device
}
// Method to add a TCP port to the Device's Ports slice safely
func (d *Device) AddPort(tcp *TCPPort) {
d.mu.Lock()
defer d.mu.Unlock()
d.Ports = append(d.Ports, tcp)
}
// Method to remove a TCP port from the Device's Ports slice safely
func (d *Device) RemovePort(tcp *TCPPort) {
d.mu.Lock()
defer d.mu.Unlock()
// Find the index of the TCP port in the Ports slice
var index int
for i, port := range d.Ports {
if port == tcp {
index = i
break
}
}
// Remove the TCP port from the slice
d.Ports = append(d.Ports[:index], d.Ports[index+1:]...)
}
现在,当您要添加或删除 TCP 端口时,可以分别使用 Device 结构的 AddPort 和 RemovePort 方法执行此操作。互斥锁确保一次只有一个 goroutine 可以修改 Ports 切片,从而提供并发安全性。
评论
2赞
DavidW
7/27/2023
这个答案看起来像 ChatGPT
评论