相关疑难解决方法(0)

Go渠道是如何实施的?

在(简要)回顾Go语言规范,有效Go和Go内存模型后,我仍然不清楚Go渠道如何在幕后工作.

他们是什么样的结构?它们的行为类似于线程安全的队列/数组.

他们的实现是否依赖于架构?

channel go

62
推荐指数
3
解决办法
9841
查看次数

如何使用频道广播消息

我是新手,我正在尝试创建一个简单的聊天服务器,客户端可以向所有连接的客户端广播消息.

在我的服务器中,我有一个goroutine(无限循环)接受连接,所有连接都由一个通道接收.

go func() {
    for {
        conn, _ := listener.Accept()
        ch <- conn
        }
}()
Run Code Online (Sandbox Code Playgroud)

然后,我为每个连接的客户端启动一个处理程序(goroutine).在处理程序内部,我尝试通过迭代通道来广播所有连接.

for c := range ch {
    conn.Write(msg)
}
Run Code Online (Sandbox Code Playgroud)

但是,我不能播放因为(我认为从阅读文档)通道需要在迭代之前关闭.我不确定何时应关闭频道,因为我想继续接受新的连接,关闭频道不会让我这样做.如果有人可以帮助我,或提供更好的方式向所有连接的客户广播消息,我们将不胜感激.

concurrency channel go goroutine

20
推荐指数
3
解决办法
2万
查看次数

在Golang中为递归函数实现生成器(yield)的惯用方法

[注意:我在Go中阅读了Python风格的生成器,这不是它的重复.]

在Python/Ruby/JavaScript/ECMAScript 6中,可以使用yield语言提供的关键字编写生成器函数.在Go中,可以使用goroutine和channel模拟它.

代码

以下代码显示了如何实现置换函数(abcd,abdc,acbd,acdb,...,dcba):

// $src/lib/lib.go

package lib

// private, starts with lowercase "p"
func permutateWithChannel(channel chan<- []string, strings, prefix []string) {
    length := len(strings)
    if length == 0 {
        // Base case
        channel <- prefix
        return
    }
    // Recursive case
    newStrings := make([]string, 0, length-1)
    for i, s := range strings {
        // Remove strings[i] and assign the result to newStringI
        // Append strings[i] to newPrefixI
        // Call the recursive case
        newStringsI …
Run Code Online (Sandbox Code Playgroud)

recursion yield generator go

18
推荐指数
2
解决办法
1万
查看次数

如何在Golang中实现内存池

我在Go中实现了一个HTTP服务器.

对于每个请求,我需要为特定的结构创建数百个对象,我有~10个这样的结构.因此,根据Go实现完成请求后,它将被垃圾收集.

因此,对于每个请求,将分配和释放大量内存.

相反,我想实现内存池以提高分配端和GC端的性能

在请求开始时,我将从池中取出并在请求提供后将其放回

从池实现方面

  1. 如何分配和释放特定类型结构的内存?
  2. 如何跟踪这个记忆分配的信息,而其他信息不是?

在内存分配和释放的情况下,还有其他任何提高性能的建议吗?

memory-management go

12
推荐指数
2
解决办法
8346
查看次数

这是Go中惯用的工作线程池吗?

我正在尝试用goroutines编写一个简单的工作池.

  • 我写的代码是惯用的吗?如果没有,那么应该改变什么呢?
  • 我希望能够将最大工作线程数设置为5并阻塞,直到工作人员可用,如果所有5个工作线都忙.我如何将此扩展到最多只有5名工作人员?我是否会产生静态的5 goroutines,然后分别给它们work_channel

码:

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func worker(id string, work string, o chan string, wg *sync.WaitGroup) {
    defer wg.Done()
    sleepMs := rand.Intn(1000)
    fmt.Printf("worker '%s' received: '%s', sleep %dms\n", id, work, sleepMs)
    time.Sleep(time.Duration(sleepMs) * time.Millisecond)
    o <- work + fmt.Sprintf("-%dms", sleepMs)
}

func main() {
    var work_channel = make(chan string)
    var results_channel = make(chan string)

    // create goroutine per item in work_channel
    go func() {
        var c = 0
        var wg …
Run Code Online (Sandbox Code Playgroud)

concurrency multithreading go goroutine

10
推荐指数
1
解决办法
2407
查看次数

如果我正确使用频道,我是否需要使用互斥锁?

如果我正确使用频道,我是否需要使用互斥锁来防止并发访问?

concurrency mutex channel go

6
推荐指数
1
解决办法
881
查看次数

非初始化通道如何表现?

我有一个结构,包含一个未初始化的通道.

当我写入它时,例程会按预期阻塞,但读者永远不会被告知管道中存在某些内容.

我很惊讶没有错误,我想知道Go是做什么的.

在下面的示例中,既不显示消息pushed也不got it打印.(取消注释初始化,它将像魅力一样工作)

type MyStruct struct {
    over chan bool
}

func main() {
    nonInitialized := &MyStruct{}
    // nonInitialized.over = make(chan bool)
    go func() {
        for i := 0; i < 10; i++ {
            select {
            case <-nonInitialized.over:
                fmt.Println("got it")
            default:
                // proceed
            }
            fmt.Println("do some stuff")
            time.Sleep(10 * time.Millisecond)
        }
        panic("took too long")
    }()
    // push on the non initialized channel
    fmt.Println("pushing")
    nonInitialized.over <- true
    fmt.Println("pushed")
}
Run Code Online (Sandbox Code Playgroud)

这是游乐场https://play.golang.org/p/76zrCuoeoh

(我知道我应该初始化频道,这不是问题的目的,我想知道Go中发生的事情与未初始化的频道.)

null initialization channel go

5
推荐指数
1
解决办法
1048
查看次数

Golang 不能用作类型结构数组或切片文字

我正在尝试在 Go 中编写一个函数,该函数采用带有目录 URL 的 JSON 并执行 BFS 以查找该目录中的文件。当我找到作为目录的 JSON 时,代码会生成一个 URL 并且应该将该 URL 加入队列。当我尝试append()在循环中创建结构时,出现错误。

type ContentResp []struct {
    Name string `json:"name"`
    ContentType string `json:"type"`
    DownloadURL string `json:"download_url"`
}
...

var contentResp ContentResp
search(contentQuery, &contentResp)

for _, cont := range contentResp {
        append(contentResp, ContentResp{Name:cont.Name, ContentType:"dir", DownloadURL:cont.contentDir.String()})
}

./bfs.go:129: undefined: Name
./bfs.go:129: cannot use cont.Name (type string) as type struct { Name string "json:\"name\""; ContentType string "json:\"type\""; DownloadURL string "json:\"download_url\"" } in array or slice literal
./bfs.go:129: undefined: ContentType …
Run Code Online (Sandbox Code Playgroud)

json struct literals go slice

5
推荐指数
1
解决办法
1万
查看次数

简单数据流:与Java相比,速度极慢

作为Java开发人员,我目前正在研究Go,因为我觉得它是一种有趣的语言.

首先,我决定采用我几个月前写的一个简单的Java项目,然后在Go中重新编写它以比较性能和(主要是实际)比较代码的可读性/复杂性.

Java代码示例如下:

public static void main(String[] args) {
    long start = System.currentTimeMillis();

    Stream<Container> s = Stream.from(new Iterator<Container>() {
        int i = 0;

        @Override
        public boolean hasNext() {
            return i < 10000000;
        }

        @Override
        public Container next() {
            return new Container(i++);
        }
    });

    s = s.map((Container _source) -> new Container(_source.value * 2));

    int j = 0;
    while (s.hasNext()) {
        s.next();
        j++;
    }

    System.out.println(System.currentTimeMillis() - start);

    System.out.println("j:" + j);
}

public static class Container {

    int value;

    public Container(int v) { …
Run Code Online (Sandbox Code Playgroud)

java performance iterator stream go

5
推荐指数
2
解决办法
793
查看次数

Golang:永远的渠道

刚问一个问题,这里发生了什么?

forever := make(chan bool)

log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
Run Code Online (Sandbox Code Playgroud)

channel go

2
推荐指数
1
解决办法
1734
查看次数

简单队列模型示例

是否有一个简单的程序,演示如何在Go中运行队列.我只需要在队列中添加1到10之类的东西,并使用另一个线程并行地从队列中拉出那些.

queue multithreading go

2
推荐指数
1
解决办法
544
查看次数

如何使变量成为线程安全的

我是Go的新手,我需要创建一个变量线程安全的。我知道在Java中您只能使用synchronized关键字,但是似乎没有类似的东西存在。有什么方法可以同步变量?

concurrency thread-safety go

0
推荐指数
1
解决办法
1236
查看次数

为什么 Go 使用通道在 goroutine 之间发送和接收数据而不是使用普通变量?

除了维基百科https://en.wikipedia.org/wiki/Channel_(programming) 的解释之外,我找不到关于这个问题的任何信息。但我对解释不满意。

渠道解决什么问题?为什么我们不直接使用普通变量来发送和接收数据呢?

go goroutine

0
推荐指数
1
解决办法
120
查看次数