我认为coroutine/goroutine在很多并发小任务必须快速执行的情况下非常有用.目前std::thread不能满足要求,因为它的成本很高.
我还认为只能通过C++库来支持coroutine/goroutine,它应该由语言的核心功能直接实现.因为coroutine/goroutine具有特殊的语义,在当前的C++标准中没有相应的概念.
如果我们添加一个新关键字cppgo,那么我们可以编写如下代码:
void f(int n)
{
...
}
int main()
{
for (int i = 0; i < 10000; ++i)
{
cppgo f(i);
}
}
Run Code Online (Sandbox Code Playgroud)
多酷啊!
C++ 1y标准是否被认为支持coroutine/goroutine?
在下面的代码中,有两个包含工作的通道A和B,在实际代码中它们是不同的结构,工作人员需要在退出之前排空两个通道.工人需要从两个渠道进来的信息.两个选择语句有效,但它非常笨拙.如果我添加default:以使它们无阻塞,则代码无法排空通道.是否有更好的方式来编写选择?
现在如果通道A没有工作,那么通道B也不会得到服务.要解决的另一个问题,但不是我的主要关注点.
测试以下代码的游乐场:
package main
import (
"fmt"
"time"
)
const (
fillCount = 10 // number of elements in each input channel
numWorkers = 3 // number of consumers.
)
func Wait() {
time.Sleep(2000 * time.Millisecond)
}
func fillChannel(work chan string, name string) {
for i := 0; i < fillCount; i++ {
work <- fmt.Sprintf("%s%d", name, i)
}
close(work) // we're finished
}
func doWork(id int, ch1 chan string, ch2 chan string, done chan …Run Code Online (Sandbox Code Playgroud) 我是golang的新手,并试图理解主要原则并使用chanels编写基于gouroutines的代码.
在我使用的其他语言中没有这样的乐器,我想知道这样的错误就像恐慌......
我的代码:
package main
import "fmt"
import (
"time"
)
type Work struct {
x,y,z int
}
func worker(in <-chan *Work, out chan<- *Work){
for w := range in {
w.z = w.x + w.y
time.Sleep(time.Duration(w.z))
out <-w
}
}
func sendWork(in chan <- *Work){
var wo *Work
wo.x, wo.y, wo.z = 1,2,3
in <- wo
in <- wo
in <- wo
in <- wo
in <- wo
}
func receiveWork(out <-chan *Work ) []*Work{
var slice []*Work
for …Run Code Online (Sandbox Code Playgroud) 我现在比较新,我在这个网站上搜索了这个问题,并且回答了问题,但是无法对我的案例实施这些答案.我有一个代码:
func receiveWork(out <-chan Work) map[string][]ChartElement {
var countedData map[string][]ChartElement
for el := range out {
countedData[el.Name] = el.Data
}
fmt.Println("This is never executed !!!")
return countedData
}
Run Code Online (Sandbox Code Playgroud)
这种方法之外的结构没有麻烦.也map不会执行(如测试恐慌这里).我知道麻烦在于将数据递增到结构中.
有一些goroutines,正在向通道发送数据,countedData方法rgabs all,应该像这样制作一个地图:
map =>
"typeOne" =>
[
ChartElement,
ChartElement,
ChartElement,
],
"typeTwo" =>
[
ChartElement,
ChartElement,
ChartElement,
]
Run Code Online (Sandbox Code Playgroud)
如何以正确的方式实现这种插入?
我正在尝试理解这段代码,不确定为什么第二轮在第一轮之前执行.如果有人能真正帮助我,那就太棒了!
func sum(a []int, c chan int) {
fmt.Println("summing: ", a)
total := 0
for _, v := range a {
total += v
}
//fmt.Println("send to c",total)
c <- total // send total to c
}
func main() {
//a := []int{7, 2, 8,134,23,23,1,23,1234,143, -9, 4, 0, 1234}
c := make(chan int)
go sum([]int{1,2,3}, c)
go sum([]int{4,5,6}, c)
x := <-c
fmt.Println(x)
x = <-c
fmt.Println(x)
}
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
summing: [4 5 6]
15
summing: [1 2 3]
6
Run Code Online (Sandbox Code Playgroud) 就像在这里我创建了一个游乐场样本:sGgxEh40ev,但无法让它工作.
quit := make(chan bool)
res := make(chan int)
go func() {
idx := 0
for {
select {
case <-quit:
fmt.Println("Detected quit signal!")
return
default:
fmt.Println("goroutine is doing stuff..")
res <- idx
idx++
}
}
}()
for r := range res {
if r == 6 {
quit <- true
}
fmt.Println("I received: ", r)
}
Run Code Online (Sandbox Code Playgroud)
输出:
goroutine is doing stuff..
goroutine is doing stuff..
I received: 0
I received: 1
goroutine is doing stuff..
goroutine is …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用通道来实现一种工作池。请看下面的代码
https://play.golang.org/p/g7aKxDoP9lf(围棋游乐场)
package main
import (
"fmt"
"time"
)
func main() {
q1 := make(chan int)
fmt.Printf("worker 1\n")
go worker1(q1)
for i := 0; i < 10; i++ {
fmt.Printf("sending: %v\n", i)
q1 <- i
}
time.Sleep(time.Second)
fmt.Printf("\n\nworker 2\n")
q2 := make(chan *int)
go worker2(q2)
for i := 0; i < 10; i++ {
fmt.Printf("sending: %v\n", i)
q2 <- &i
}
time.Sleep(time.Second)
}
func worker1(qTodo <-chan int) {
var curr int
for {
select {
case curr = <-qTodo: …Run Code Online (Sandbox Code Playgroud) 我的代码如下:
package main
import (
"fmt"
)
func main() {
c1 := make(chan int)
fmt.Println("push c1: ")
c1 <- 10
g1 := <- c1
fmt.Println("get g1: ", g1)
}
Run Code Online (Sandbox Code Playgroud)
当我使用 delve 进行调试时,它会打印以下结果:
push c1:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
D:/Go/projects/hello-world/src/ch9/code9_6/code1.go:10 +0xde
Process 6276 has exited with status 2
Run Code Online (Sandbox Code Playgroud)
我不知道为什么,这只是一个简单的渠道示例,我创建了一个渠道,向其发送价值并从中获取价值,仅此而已,有人可以告诉我为什么,以及如何纠正它,非常感谢。
在过去一天左右的时间里,我一直在努力解决问题,以找出创建N个并发函数的最佳方法,这些函数在Go中以相同的时间间隔定期调用。我希望能够指定任意数量的功能,让它们全部同时定期运行,并在指定的时间后结束它们。
现在,我有一个可行的解决方案,但是必须为每个并发函数创建一个新的代码。我也不确定如何正确使用sync.WaitGroup,因为我当前的实现导致程序永无休止(只是卡在了wg.Wait()的最后)
我简要地看了一下名为Multitick的自动报价包装器,但不确定如何实现它。也许Multitick可能是这里的解决方案?
func main() {
N := 10
var wg sync.WaitGroup
wg.Add(N)
quit := make(chan struct{})
for i := 0; i < N; i++ {
tick := time.NewTicker(500 * time.Millisecond)
go func(t *time.Ticker) {
for a := range tick.C {
select {
case <-quit:
break
default:
fmt.Println(a) // do something on tick
}
}
wg.Done()
}(tick)
}
time.Sleep(10 * time.Second)
close(quit)
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
因此,此解决方案有效,可以以适当的间隔同时执行所有代码,并在10秒后完成,但实际上并没有退出程序,最终挂在wg.Wait()行上。另外,每个并发函数调用都使用自己的代码-我可以通过任何方式使用一个“主”代码来运行所有函数吗?
提前致谢!这是我第一次真正研究Go的并发性。
我正在编写一个调用其他微服务的微服务,用于很少更新的数据(一天一次或一个月一次)。所以我决定创建缓存,并实现了这个接口:
type StringCache interface {
Get(string) (string, bool)
Put(string, string)
}
Run Code Online (Sandbox Code Playgroud)
在内部,它只是map[string]cacheItem,在哪里
type cacheItem struct {
data string
expire_at time.Time
}
Run Code Online (Sandbox Code Playgroud)
我的同事说它不安全,我需要在我的方法中添加互斥锁,因为它将被 http 处理程序函数的不同实例并行使用。我有一个测试,但它没有检测到数据竞争,因为它在一个 goroutine 中使用缓存:
func TestStringCache(t *testing.T) {
testDuration := time.Millisecond * 10
cache := NewStringCache(testDuration / 2)
cache.Put("here", "this")
// Value put in cache should be in cache
res, ok := cache.Get("here")
assert.Equal(t, res, "this")
assert.True(t, ok)
// Values put in cache will eventually expire
time.Sleep(testDuration)
res, ok = cache.Get("here")
assert.Equal(t, res, "")
assert.False(t, ok) …Run Code Online (Sandbox Code Playgroud)