Synchronous concurrency: Difference between revisions

Content added Content deleted
(Better example)
(→‎{{header|Go}}: As documented, bufio.ReadString is preferred over bufio.ReadLine, this also removes the issue with long lines)
Line 963: Line 963:


import (
import (
"bufio"
"fmt"
"fmt"
"bufio"
"io"
"io"
"os"
"os"
)
)


// main, one of two goroutines used, will function as the "reading unit"
// main, one of two goroutines used, will function as the "reading unit"
func main() {
func main() {
// get file open first
// get file open first
f, err := os.Open("input.txt")
f, err := os.Open("input.txt")
if err != nil {
if err != nil {
fmt.Println(err)
fmt.Println(err)
return
return
}
}
defer f.Close()
defer f.Close()
lr := bufio.NewReader(f)
lr := bufio.NewReader(f)


// that went ok, now create communication channels,
// that went ok, now create communication channels,
// and start second goroutine as the "printing unit"
// and start second goroutine as the "printing unit"
lines := make(chan string)
lines := make(chan string)
count := make(chan int)
count := make(chan int)
go printer(lines, count)
go printer(lines, count)


for {
for {
line, prefix, err := lr.ReadLine()
switch line, err := lr.ReadString('\n'); err {
case nil:
switch {
lines <- line
case err == io.EOF:
continue
case err != nil:
case io.EOF:
fmt.Println(err)
default:
case prefix:
fmt.Println("unexpected long line")
fmt.Println(err)
}
default:
break
lines <- string(line)
}
continue

}
// this represents the request for the printer to send the count
break
close(lines)
}
// this represents the request for the printer to send the count
// wait for the count from the printer, then print it, then exit
fmt.Println("Number of lines:", <-count)
close(lines)
// wait for the count from the printer, then print it, then exit
fmt.Println("Number of lines:", <-count)
}
}


func printer(in <-chan string, count chan<- int) {
func printer(in <-chan string, count chan<- int) {
c := 0
c := 0
// loop as long as in channel stays open
// loop as long as in channel stays open
for s := range in {
for s := range in {
fmt.Println(s)
fmt.Print(s)
c++
c++
}
}
// make count available on count channel, then return (terminate goroutine)
// make count available on count channel, then return (terminate goroutine)
count <- c
count <- c
}</lang>
}</lang>