我有要处理的网址列表,但我想一次运行最大数量的goroutine。例如,如果我有30个网址,那么我只希望10个goroutine并行工作。
我对此的尝试如下:
parallel := flag.Int("parallel", 10, "max parallel requests allowed")
flag.Parse()
urls := flag.Args()
var wg sync.WaitGroup
client := rest.Client{}
results := make(chan string, *parallel)
for _, url := range urls {
wg.Add(1)
go worker(url, client, results, &wg)
}
for res := range results {
fmt.Println(res)
}
wg.Wait()
close(results)
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果我创建一个大小为并行的缓冲通道,那么该代码将阻塞,直到我读出结果通道为止,这将取消阻塞我的代码并允许生成另一个goroutine。但是,此代码似乎在处理完所有网址后不会阻塞。有人可以向我解释如何使用通道限制运行的goroutine的数量吗?
我认为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)
如何以正确的方式实现这种插入?
我正在使用golang来实现一个简单的事件驱动工作者.就像这样:
go func() {
for {
select {
case data := <-ch:
time.Sleep(1)
someGlobalMap[data.key] = data.value
}
}
}()
Run Code Online (Sandbox Code Playgroud)
主函数将创建几个goroutine,每个都将执行以下操作:
ch <- data
fmt.Println(someGlobalMap[data.key])
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) 在过去一天左右的时间里,我一直在努力解决问题,以找出创建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的并发性。
我是 Go 新手,正在寻找使用 goroutine 的正确net/http方法fasthttp。不幸的是,那里没有很多fasthttp客户示例。
我找到了以下代码:(示例1)
package main
import (
"bufio"
"fmt"
"github.com/valyala/fasthttp"
"log"
"net"
"os"
"sync"
"time"
)
func grabPage(fastClient *fasthttp.Client, i int, wg *sync.WaitGroup) {
defer wg.Done()
_, body, err := fastClient.GetTimeout(nil, "https://en.wikipedia.org/wiki/Immanuel_Kant", time.Duration(time.Second*20))
if err != nil {
log.Fatal(err)
}
f, err := os.Create(fmt.Sprintf("./data/%d.txt", i))
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
w.Write(body)
}
func main() {
var wg sync.WaitGroup
total := 500
c …Run Code Online (Sandbox Code Playgroud)