这是@Jimt编写的Go中的工作者和控制器模式的一个很好的例子,回答" 是否有一些优雅的方式来暂停和恢复golang中的任何其他goroutine? "
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
// Possible worker states.
const (
Stopped = 0
Paused = 1
Running = 2
)
// Maximum number of workers.
const WorkerCount = 1000
func main() {
// Launch workers.
var wg sync.WaitGroup
wg.Add(WorkerCount + 1)
workers := make([]chan int, WorkerCount)
for i := range workers {
workers[i] = make(chan int)
go func(i int) {
worker(i, workers[i])
wg.Done()
}(i)
}
// Launch controller routine.
go func() { …Run Code Online (Sandbox Code Playgroud) 我正在阅读The Go Programming Language Specifications并发现自己并非真正理解封闭体后的"()":
在Function literals:
func(ch chan int){ch < - ACK} (replyChan) `
在Defer statements例子中:
// f returns 1
func f() (result int) {
defer func() {
result++
}() // why and how?
return 0
}
Run Code Online (Sandbox Code Playgroud)
我不清楚在封闭体之后添加和使用"()"的原因,希望有人能够清楚地解释这一点.
我正在研究Go项目一个月.好的是Go非常高效.但经过一个月的开发,我已经有了数千行代码和许多代码packages.为了避免导入周期对我来说是一个主要的问题,任何时候我遇到导入周期错误,我不知道第一次问题可能在哪里.
Go编译器也只有非常简单的通知,总是不能很好地快速定位问题,如:main.go:7:3: import cycle not allowed.它只会帮助您了解哪个文件可能导致问题,但不会更深入.由于import关系在代码增长时变得越来越复杂,我迫切希望知道如何在Go中更有效地避免导入周期.任何帮助深表感谢.
这是我的代码(运行):
package main
import "fmt"
func main() {
var whatever [5]struct{}
for i := range whatever {
fmt.Println(i)
} // part 1
for i := range whatever {
defer func() { fmt.Println(i) }()
} // part 2
for i := range whatever {
defer func(n int) { fmt.Println(n) }(i)
} // part 3
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
1
2
3
4
4
3
2
1
0
4
4
4
4
4
问题:第2部分和第3部分有什么区别?为什么第2部分输出"44444"而不是"43210"?
就我而言,我有成千上万的goroutines同时工作work().我也有一个sync()goroutine.当sync启动时,我需要任何其他的goroutine同步作业完成后暂停了一段时间.这是我的代码:
var channels []chan int
var channels_mutex sync.Mutex
func work() {
channel := make(chan int, 1)
channels_mutex.Lock()
channels = append(channels, channel)
channels_mutex.Unlock()
for {
for {
sync_stat := <- channel // blocked here
if sync_stat == 0 { // if sync complete
break
}
}
// Do some jobs
if (some condition) {
return
}
}
}
func sync() {
channels_mutex.Lock()
// do some sync
for int i := 0; i != len(channels); i++ …Run Code Online (Sandbox Code Playgroud) 我想在WatchKit中创建一个带动画的按钮,但似乎我无法找到一种方法来修改WKInterfaceButton或将图像拖动到故事板中的按钮.任何帮助表示赞赏.
这是目录树:
+/project
+---/bin
+---/pkg
+---/src
+---/client_test
+---client_test.go
+---main.go
Run Code Online (Sandbox Code Playgroud)
在main.go中:
package main
import ("client_test")
func main() {
client_test.Send()
}
Run Code Online (Sandbox Code Playgroud)
在client_test.go中:
package client_test
func Send() {
}
Run Code Online (Sandbox Code Playgroud)
错误:
src/main.go|8| imported and not used: "client_test"
src/main.go|32| undefined: client_test
Run Code Online (Sandbox Code Playgroud)
我已经阅读了如何在golang中使用自定义包?而且我觉得我和这个家伙有同样的解决方案,但我只是不知道如何解决这个问题.请帮忙.
去环境:
GOARCH="amd64"
GOBIN="/usr/local/go/bin"
GOCHAR="6"
GOEXE=""
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread -fno-common"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/staff/projects/Minigame_Server" (that's exactly my working directory)
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
CGO_ENABLED="1"
Run Code Online (Sandbox Code Playgroud) 我已经被这个问题困扰了几个小时:
我有一个主进程作为 TCP 服务器,主进程调用 Fork(),将其 net.Listener() 的 FD 传递给子进程。然后子进程可以使用 net.Filelistener() 来继承这个 FD。
我通过很多开源代码研究过这个问题,也做了一些实验。但不幸的是,这些解决方案目前都没有让我满意,因为它们不可移植,您还需要许多危险的低级工作。
如果有任何解决方案可以将 net.Listener() 的 FD 安全地传递给子进程,我很高兴知道。
我现在尝试过的:
环境值,不可移植,会导致许多 FD 的混乱,不安全,因为可以从外部更改。
Dup FD & ClearFD_CLOEXEC然后是 exec/fork,可移植但不受 Go API 支持,syscall.NoCloseOnExec()提交给开发团队的更改被拒绝,因为他们希望保持系统调用干净。
设置SO_REUSEADDR以便子进程可以立即侦听端口,在此之前关闭父进程的侦听器。失败,不可移植,Go API 不支持,也不安全。
exec.Command.ExtraFiles(),不知道如何从子进程中获取继承的 FD,我是否需要一个配置文件来保存 FD 和名称?此解决方案也有一个错误,请阅读 exec 的文档以获取更多详细信息。
好吧,我已经为这个问题编写了一个简单的测试用例(使用解决方案 4):
https://github.com/reckhou/go-fd-pass-test
还包括 OS X 和 Linux 上的 2 个可执行文件。我尝试了 Go 1.1 & Go 1.1.1,但这个问题仍然存在。
由于我正在运行Go程序作为服务器,我需要一些机制来捕获恐慌日志,如果出现任何问题,以便以后进行分析和调试.是否有任何有效的方法可以轻松地在Unix下获取Go程序的恐慌日志?你们能介绍一下你的经历吗?谢谢 :)
这是我的代码的一部分:
在啊:
class classA
{
public:
void (*function_a)(void);
classA();
void function_a();
};
Run Code Online (Sandbox Code Playgroud)
在a.cpp中:
void classA::classA()
{
(*function_a)() = function_a;
}
void classA::function_a()
{
return;
}
Run Code Online (Sandbox Code Playgroud)
我想得到function_a的地址并将其保存到void(*function_a)(void),但是我得到编译错误"表达式不可分配".我该怎么做才能解决这个问题?