小编Son*_*Gao的帖子

在x86上是Go atomic的增量运算符吗?

这里有一些背景知识:
我需要在go例程之间共享一个计数器变量,用于类似漏桶的东西.我知道在Effective Go,并发部分中有一个漏桶的例子,但是我需要跟踪的数量可能非常大,我觉得使用频道中的元素数来跟踪它是低效的.所以我正在考虑在不同的例程之间使用共享变量来跟踪数字.

据我所知,没有显式配置,所有go例程都映射到一个线程.但是,如果我在多核计算机上为程序分配多个线程,那么增量运算符是原子的吗?它是针对不同的数据类型(都是一样的int32,float32等等)在不同的机器(x86_32,x86_64,arm)?

更具体的说,如果我counter += 1000在一个例程中,counter -= 512在另一个例程中,并且这两个例程恰好在两个线程中运行,该怎么办?我需要担心线程安全吗?我要把枪锁上counter吗?

concurrency atomic thread-safety go

16
推荐指数
1
解决办法
2024
查看次数

如何在数据链路层(以太网)监听并在传输层响应

我想要做的是侦听 IPv6 的以太网帧并响应特定端口上的 UDP 调用。

我能够捕获我关心的以太网帧并解析出 UDP 有效负载,但是当我尝试回显该有效负载时,我遇到了问题。这是我的“服务器”代码:

func main() {
    fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_IPV6)))
    iface, err := net.InterfaceByName("lo")
    if err != nil {
        log.Fatal(err)
    }

    err = syscall.BindToDevice(fd, iface.Name)
    if err != nil {
        log.Fatal(err)
    }

    for {
        buf := make([]byte, iface.MTU)
        n, callerAddr, err := syscall.Recvfrom(fd, buf, 0)
        if err != nil {
            log.Fatal(err)
        }
        data := buf[:n]
        packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.Default)
        udpPacket := packet.Layer(layers.LayerTypeUDP)
        if udpPacket != nil {
            udpPck, _ := udpPacket.(*layers.UDP)

            // …
Run Code Online (Sandbox Code Playgroud)

unix sockets go

7
推荐指数
1
解决办法
365
查看次数

Go的缓冲通道是否无锁?

Go的缓冲通道本质上是一个线程安全的FIFO队列.(请参阅是否可以将Go的缓冲通道用作线程安全队列?)

我想知道它是如何实现的.它是无锁的,如有多个读或写线程的无锁队列吗?

Go的src目录(grep -r Lock .|grep chan)中的greping 给出了以下输出:

./pkg/runtime/chan.c:   Lock;
./pkg/runtime/chan_test.go: m.Lock()
./pkg/runtime/chan_test.go: m.Lock() // wait
./pkg/sync/cond.go: L Locker // held while observing or changing the condition
Run Code Online (Sandbox Code Playgroud)

但是不要锁定我的机器(MacOS,intel x86_64).有没有官方资源来验证这个?

thread-safety go lockless

6
推荐指数
2
解决办法
921
查看次数

标签 统计

go ×3

thread-safety ×2

atomic ×1

concurrency ×1

lockless ×1

sockets ×1

unix ×1