是否有可能以一种简单的方式来做相当于Java的工作
wait(long timeMillis)
Run Code Online (Sandbox Code Playgroud)
在指定的时间内在监视器上(互斥锁+ cond,粗略地)等待,如果没有信号则返回?
我在文档中找不到任何东西或在谷歌上搜索,虽然它当然可以通过制作一个WaitGroup和定时器goroutine pop来玩一些游戏,但这似乎很乏味/烦人/低效才能获得这个简单的功能(这是我遇到的任何底层系统线程库直接支持的方式)
编辑:是的我们都阅读了http://www.golang-book.com/10/index.htm以及https://blog.golang.org/pipelines - 再次,创建更多线程是一个"坏"(非性能的解决方案,并且渠道也不太适合这个.想象一个用例是一个典型的并发服务器Join()方法......(请不要告诉我反转控件并使用一个Listener模式.你并不总是可以更改你正在使用的API. ..)
您可以使用通道实现支持仅广播(无信号)的条件变量.以下是它的快速要点:https: //gist.github.com/zviadm/c234426882bfc8acba88f3503edaaa36#file-cond2-go
您也可以使用这种替换通道并在代码中关闭旧通道的技术.Gist中的代码使用unsafe.Pointer和atomic操作来允许调用'Broadcast'而不获取主sync.Locker.但是,在您自己的代码中,通常情况下,您应该从获取锁中进行广播,这样您就不需要执行任何不安全/原子的操作.
虽然此方法有效,但您可能还需要结帐:https://godoc.org/golang.org/x/sync/semaphore.如果你制作一个限制为1的加权信号量,这也将为你提供所需的所有能力,这也是公平的.
从 Go 1.21 开始,有一种方法可以使用 new 来做到这一点context.AfterFunc。甚至还有这样的例子:
package main\n\nimport (\n "context"\n "fmt"\n "sync"\n "time"\n)\n\nfunc main() {\n waitOnCond := func(ctx context.Context, cond *sync.Cond, conditionMet func() bool) error {\n stopf := context.AfterFunc(ctx, func() {\n // We need to acquire cond.L here to be sure that the Broadcast\n // below won\'t occur before the call to Wait, which would result\n // in a missed signal (and deadlock).\n cond.L.Lock()\n defer cond.L.Unlock()\n\n // If multiple goroutines are waiting on cond simultaneously,\n // we need to make sure we wake up exactly this one.\n // That means that we need to Broadcast to all of the goroutines,\n // which will wake them all up.\n //\n // If there are N concurrent calls to waitOnCond, each of the goroutines\n // will spuriously wake up O(N) other goroutines that aren\'t ready yet,\n // so this will cause the overall CPU cost to be O(N\xc2\xb2).\n cond.Broadcast()\n })\n defer stopf()\n\n // Since the wakeups are using Broadcast instead of Signal, this call to\n // Wait may unblock due to some other goroutine\'s context becoming done,\n // so to be sure that ctx is actually done we need to check it in a loop.\n for !conditionMet() {\n cond.Wait()\n if ctx.Err() != nil {\n return ctx.Err()\n }\n }\n\n return nil\n }\n\n cond := sync.NewCond(new(sync.Mutex))\n\n var wg sync.WaitGroup\n for i := 0; i < 4; i++ {\n wg.Add(1)\n go func() {\n defer wg.Done()\n\n ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)\n defer cancel()\n\n cond.L.Lock()\n defer cond.L.Unlock()\n\n err := waitOnCond(ctx, cond, func() bool { return false })\n fmt.Println(err)\n }()\n }\n wg.Wait()\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2257 次 |
| 最近记录: |