--
A scalable lock-free channel.
go get github.com/OneOfOne/lfchan
import (
"fmt"
"github.com/OneOfOne/lfchan"
)
func main() {
ch := lfchan.New() // or
// ch := lfchan.NewSize(10) // buffered channel
go ch.Send("hello", true)
fmt.Printf("%s world", ch.Recv(true).(string))
}
go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" type [pkgName or . to embed the chan in the current package]
# primitve type
go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" string internal/stringChan
# or for using a non-native type
go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" github.com/OneOfOne/cmap.CMap internal/cmapChan
go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" github.com/OneOfOne/cmap.CMap
package main
// go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" string internal/stringChan
import (
"fmt"
"github.com/YOU/internal/stringChan"
)
func main() {
ch := stringChan.New() // or
// ch := stringChan.NewSize(10) // buffered channel
go func() {
go ch.Send("lfchan", true)
ch.Send("hello", true)
}()
for s, ok := ch.Recv(true); ok; s, ok = ch.Recv(true) {
fmt.Print(s, " ")
}
fmt.Println()
}
package main
// go run "$GOPATH/src/github.com/OneOfOne/lfchan/gen.go" "[]*node" .
import (
"fmt"
)
type node struct {
v int
}
func main() {
// notice how for embeded types the new func is called "new[Size]{TypeName}Chan()
ch := newNodeChan() // or
// ch := newSizeNodeChan(10) // buffered channel
go func() {
for i := 0; i < 10; i++ {
ch.Send([]*Node{{i}, {i*i}}, true)
}
}()
for ns, ok := ch.Recv(true); ok; ns, ok = ch.Recv(true) {
for i, n := range ns {
fmt.Println(i, n.v)
}
}
}
Doesn't scale correctly on true SMP systems (issue #3).
Under high concurrency, ch.Len() can return -1 (issue #2)
Fixed by commit bdddd90.
typed channels can't handle zero value primitve types correctly,
for example it can't handle sending 0 on an int channel Fixed.
gen.go can't handle maps to non-native types.
# Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
# Linux 4.4.5 x86_64
➜ go test -bench=. -benchmem -cpu 1,4,8 -benchtime 10s
BenchmarkLFChan 100000000 157 ns/op 8 B/op 1 allocs/op
BenchmarkLFChan-4 100000000 187 ns/op 8 B/op 1 allocs/op
BenchmarkLFChan-8 100000000 168 ns/op 8 B/op 1 allocs/op
BenchmarkChan 200000000 96.2 ns/op 8 B/op 1 allocs/op
BenchmarkChan-4 50000000 244 ns/op 8 B/op 1 allocs/op
BenchmarkChan-8 50000000 323 ns/op 8 B/op 1 allocs/op
PASS
ok github.com/OneOfOne/lfchan 124.067s
check issue #3 for more benchmarks and updates.
runtime.Gosched
?time.Sleep
causes random allocations at times.
sync/atomic.Value
has access to internal
funcs which can control the scheduler, however user code can't do that.This project is released under the Apache v2. licence. See LICENCE for more details.