Golang中的select语句可以同时等待互斥锁和通道。

huangapple go评论89阅读模式
英文:

Golang select wait on both a mutex lock and a channel

问题

在Go语言中,可以使用select语句同时等待多个通道。例如:

package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()
	fibonacci(c, quit)
}

(摘自https://go.dev/tour/concurrency/5)

是否有一种机制可以类似地使用互斥锁(mutex lock),在等待通道或互斥锁可用时进行等待?类似这样:

package main

import "fmt"
import "sync"

func fibonacci(c chan int, mu sync.Mutex) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case mu.Lock():
			fmt.Println("locked")
			return
		}
	}
}

func main() {
	c := make(chan int)
	var mu sync.Mutex
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		mu.Lock()
	}()
	fibonacci(c, mu)
}

实际的使用场景是,我将一个context传递给一个函数,该函数可能会在互斥锁上等待一段时间,我希望能够通过上下文中止等待。

英文:

In golang it is possible to use a select statement to wait on multiple channels at a time. For example,

package main

import &quot;fmt&quot;

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c &lt;- x:
			x, y = y, x+y
		case &lt;-quit:
			fmt.Println(&quot;quit&quot;)
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i &lt; 10; i++ {
			fmt.Println(&lt;-c)
		}
		quit &lt;- 0
	}()
	fibonacci(c, quit)
}

(Lifted from https://go.dev/tour/concurrency/5)

Is there any mechanism to do something similar with a mutex lock, where you wait for either a channel or for a mutex lock to become available? Something like:

package main

import &quot;fmt&quot;
import &quot;sync&quot;

func fibonacci(c chan int, mu sync.Mutex) {
	x, y := 0, 1
	for {
		select {
		case c &lt;- x:
			x, y = y, x+y
		case mu.Lock():
			fmt.Println(&quot;locked&quot;)
			return
		}
	}
}

func main() {
	c := make(chan int)
	var mu sync.Mutex
	go func() {
		for i := 0; i &lt; 10; i++ {
			fmt.Println(&lt;-c)
		}
		mu.Lock()
	}()
	fibonacci(c, quit, mu)
}

The actual use scenario is that I'm passing in a context to a function that might be waiting on a mutex lock for a while, and I'd like to be able to abort the wait through the context.

答案1

得分: 2

有没有一种机制可以类似于互斥锁,等待通道或互斥锁可用的情况?

没有。

你必须重新设计,例如通过用基于通道的信号量替换互斥锁。

英文:

> Is there any mechanism to do something similar with a mutex lock, where you wait for either a channel or for a mutex lock to become available?

No.

You must redesign, e.g. by replacing the mutex with a channel based semaphore.

huangapple
  • 本文由 发表于 2022年10月1日 14:29:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/73916277.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定