在(简要)回顾Go语言规范,有效Go和Go内存模型后,我仍然不清楚Go渠道如何在幕后工作.
他们是什么样的结构?它们的行为类似于线程安全的队列/数组.
他们的实现是否依赖于架构?
我是新手,我正在尝试创建一个简单的聊天服务器,客户端可以向所有连接的客户端广播消息.
在我的服务器中,我有一个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)
但是,我不能播放因为(我认为从阅读文档)通道需要在迭代之前关闭.我不确定何时应关闭频道,因为我想继续接受新的连接,关闭频道不会让我这样做.如果有人可以帮助我,或提供更好的方式向所有连接的客户广播消息,我们将不胜感激.
[注意:我在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) 我在Go中实现了一个HTTP服务器.
对于每个请求,我需要为特定的结构创建数百个对象,我有~10个这样的结构.因此,根据Go实现完成请求后,它将被垃圾收集.
因此,对于每个请求,将分配和释放大量内存.
相反,我想实现内存池以提高分配端和GC端的性能
在请求开始时,我将从池中取出并在请求提供后将其放回
从池实现方面
在内存分配和释放的情况下,还有其他任何提高性能的建议吗?
我正在尝试用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) 如果我正确使用频道,我是否需要使用互斥锁来防止并发访问?
我有一个结构,包含一个未初始化的通道.
当我写入它时,例程会按预期阻塞,但读者永远不会被告知管道中存在某些内容.
我很惊讶没有错误,我想知道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中发生的事情与未初始化的频道.)
我正在尝试在 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) 作为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) 刚问一个问题,这里发生了什么?
forever := make(chan bool)
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
Run Code Online (Sandbox Code Playgroud) 是否有一个简单的程序,演示如何在Go中运行队列.我只需要在队列中添加1到10之类的东西,并使用另一个线程并行地从队列中拉出那些.
我是Go的新手,我需要创建一个变量线程安全的。我知道在Java中您只能使用synchronized
关键字,但是似乎没有类似的东西存在。有什么方法可以同步变量?
除了维基百科https://en.wikipedia.org/wiki/Channel_(programming) 的解释之外,我找不到关于这个问题的任何信息。但我对解释不满意。
渠道解决什么问题?为什么我们不直接使用普通变量来发送和接收数据呢?