当我在下面运行下面的代码片段时,它看起来总是打印值20000000.当我创建更多的go例程来增加没有锁定的计数器时,它显示了类似的行为。但是不存在某种竞争条件吗?谢谢!
package main
import "fmt"
const (
N_INCREMENTS = 10000000
)
func main() {
var counter int = 0
donechan := make(chan bool)
go func(done chan<- bool) {
for i := 0; i < N_INCREMENTS; i++ {
counter++
}
done <- true
}(donechan)
for i := 0; i < N_INCREMENTS; i++ {
counter++
}
_ = <-donechan
fmt.Println("Count: ", counter)
}
答案 0 :(得分:1)
runtime.GOMAXPROCS(0)
将报告可以并行运行的goroutine的数量。如果值为1,您可能不会观察到不同步 package rembrandt.bin
import rembrandt.obj.*
import saskia.bin.Configuration
import rembrandt.io.*
import org.apache.log4j.*
import org.apache.commons.cli.*
import java.util.jar.Manifest
import java.util.jar.Attributes
class Rembrandt {
/**
* Main method.
*/
static void main(args) {
def rembrandt, conf, conffilepath
Options o = new Options()
o.addOption("conf", true, "Configuration file")
o.addOption("gui", true, "Activates a graphic GUI")
o.addOption("help", false, "Gives this help information")
CommandLineParser parser = new GnuParser()
CommandLine cmd = parser.parse(o, args)
if (cmd.hasOption("help")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "java rembrandt.bin.Rembrandt", o )
System.exit(0)
}
if (!cmd.hasOption("conf")) {
conffilepath = Configuration.defaultconf
log.info "No configuration file given. Using default configuration file."
} else {
conffilepath = cmd.getOptionValue("conf")
log.info "Configuration file $conffilepath given."
}
conf = Configuration.newInstance(conffilepath)
rembrandt = new Rembrandt(conf)
log.info "Rembrandt version ${Rembrandt.getVersion()}. Welcome."
if (cmd.hasOption("gui")) {
RembrandtGui gui = new RembrandtGui(rembrandt, conf)//)
gui.start()
log.info "Rembrandt GUI started."
} else {
log.info "Invoking reader ${rembrandt.inputreader.class.name} to parse the input stream."
List<Document> docs = rembrandt.loadDocuments()
log.info "Got ${docs.size()} doc(s). "
// give labels if the doc does not have...
String docid_header
if (rembrandt.inputFileName)
docid_header = rembrandt.inputFileName
else
docid_header = 'stdin'
rembrandt.printHeader()
/* stats stuff */
def stats = new DocStats(docs.size())
stats.begin()
docs.eachWithIndex { doc, i->
if (!doc.docid) doc.docid = docid_header+"-"+(i+1)
stats.beginDoc(doc.docid)
doc = rembrandt.releaseRembrandtOnDocument(doc)
rembrandt.printDoc(doc)
stats.endDoc()
stats.printMemUsage()
}
stats.end()
rembrandt.printFooter()
log.info "All Done. Have a nice day."
}
}
}
变量的任何“副作用”。
如果您首先在程序开头将其设置为counter
:
2
您将立即看到效果:
runtime.GOMAXPROCS(2)
如果您想获得竞争条件的证据,请提供Count: 10319575
参数。输出-race
:
-race
(请注意,竞争检测器仅适用于64位Go分布。)
在Go操场上,GOMAXPROCS默认为==================
WARNING: DATA RACE
Read by goroutine 6:
main.main.func1()
V:/workspace/IczaGo/src/play/play.go:20 +0x48
Previous write by main goroutine:
main.main()
V:/workspace/IczaGo/src/play/play.go:26 +0xef
Goroutine 6 (running) created at:
main.main()
V:/workspace/IczaGo/src/play/play.go:23 +0xbc
==================
。此行将打印上一个值并将其设置为1
:
2
输出(在Go Playground上尝试):
fmt.Println("Previous GOMAXPROCS:", runtime.GOMAXPROCS(2))
另请注意,GOMAXPROCS在1.5之前的Go分布中设置为Previous GOMAXPROCS: 1
Count: 12844130
。从1.5开始,GOMAXPROCS的默认值是运行程序的计算机上可用的CPU核心数。