英文:
Conditional Go Routine/Channel
问题
我想将统计程序设为有条件运行,只在某些情况下运行,否则会浪费一半的时间。目前,我有一个goroutine作为生产者,通过缓冲通道向两个消费者goroutine提供数据。有没有办法使统计程序有条件运行,或者有没有更好的模式可以遵循?非常感谢您提前的任何帮助!
func main() {
options()
go produce(readCSV(loc))
go process()
go statistics() // 仅在标志位为真时运行
<-done
}
func produce(entries [][]string) {
regex, err := regexp.Compile(reg)
if err != nil {
log.Error(reg + ", 不是一个有效的正则表达式")
} else {
for _, each := range entries {
if regex.MatchString(each[col]) {
matches <- each
stats <- each // 仅在标志位为真时运行
}
}
}
done <- true
}
func process() {
for {
match := <-matches
if len(match) != 0 {
// 处理
}
}
}
func statistics() {
for {
stat := <-stats
if len(stat) != 0 {
// 统计
}
}
}
英文:
I would like to make the statistics routine conditional so that it only runs on certain cases otherwise it will waste cycles half the time. Right now I have one go routine act as a producer to feed the two consumer routines via buffered channels. Is there a way I can make it so the statistics routine is conditional or is there a better pattern I should follow? Thanks in advance for any and all help!
func main() {
options()
go produce(readCSV(loc))
go process()
go statistics() // only on flag
<-done
}
func produce(entries [][]string) {
regex, err := regexp.Compile(reg)
if err != nil {
log.Error(reg + ", is not a valid regular expression")
} else {
for _, each := range entries {
if regex.MatchString(each[col]) {
matches <- each
stats <- each // only on flag
}
}
}
done <- true
}
func process() {
for {
match := <-matches
if len(match) != 0 {
// PROCESS
}
}
}
func statistics() {
for {
stat := <-stats
if len(stat) != 0 {
// STATISTICS
}
}
}
答案1
得分: 1
这个条件语句没有问题:
var stats chan []string // 不要初始化 stats.
func main() {
options()
go produce(readCSV(loc))
go process()
if flag {
stats = make(chan []string, 1024)
go statistics() // 只在 flag 为真时执行
}
<-done
}
func produce(entries [][]string) {
regex, err := regexp.Compile(reg)
if err != nil {
log.Error(reg + " 不是一个有效的正则表达式")
} else {
for _, each := range entries {
if regex.MatchString(each[col]) {
matches <- each
if stats != nil {
stats <- each // 只在 flag 为真时执行
}
}
}
}
close(done)
}
func process() {
for {
select {
case match := <-matches:
if len(match) != 0 {
// 处理
}
case <-done:
return
}
}
}
func statistics() {
for {
select {
case stat := <-stats:
if len(stat) != 0 {
// 统计
}
case <-done:
return
}
}
}
英文:
There is nothing wrong with making this conditional:
var stats chan []string // Don't initialize stats.
func main() {
options()
go produce(readCSV(loc))
go process()
if flag {
stats = make(chan []string, 1024)
go statistics() // only on flag
}
<-done
}
func produce(entries [][]string) {
regex, err := regexp.Compile(reg)
if err != nil {
log.Error(reg + ", is not a valid regular expression")
} else {
for _, each := range entries {
if regex.MatchString(each[col]) {
matches <- each
if stats != nil {
stats <- each // only on flag
}
}
}
}
close(done)
}
func process() {
for {
select {
case match := <-matches:
if len(match) != 0 {
// PROCESS
}
case <-done:
return
}
}
}
func statistics() {
for {
select {
case stat := <-stats:
if len(stat) != 0 {
// STATISTICS
}
case <-done:
return
}
}
}
答案2
得分: 0
也许你正在寻找flag包。
import "flag"
var withStats = flag.Boolean("s", false, "进行统计")
func main() {
flag.Parse()
...
if *withStats == true {
t := statType
size := 100
stats := make(chan, t, size)
go statistics() // 仅在标志上
}
...
}
英文:
Perhaps you're looking for the flag package.
import "flag"
var withStats = flag.Boolean("s", false, "Do statistics")
func main() {
flag.Parse()
...
if *withStats == true {
t := statType
size := 100
stats := make(chan, t, size)
go statistics() // only on flag
}
...
}
答案3
得分: 0
如果你在代码中从多个地方更新统计数据,你可能想要添加一些辅助方法。类似这样:
type stats struct {
ch chan []string
}
func (s *stats) update(a []string) {
if s != nil {
s.ch <- a
}
}
func (s *stats) start() {
if s != nil {
s.ch = make(chan []string)
go statistics()
}
}
var s *stats
if enabled {
s = new(stats)
}
s.start()
// 代码的其他部分
s.update(each)
希望这能帮到你!
英文:
If you update statistics from many places in your code you might want to add some helper methods. Something like:
type stats struct {
ch chan []string
}
func (s *stats) update(a []string) {
if s != nil {
s.ch <- a
}
}
func (s *stats) start() {
if s != nil {
s.ch = make(chan []string)
go statistics()
}
}
var s *stats
if enabled {
s = new(stats)
}
s.start()
// later in the code
s.update(each)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论