done : = make ( chan bool )
/// [...]
done <- true
done : = make ( chan struct { } )
// [...]
done <- struct { } { }
func main ( ) {
done : = make ( chan struct { } )
go func ( ) {
// stuff
done <- struct { } { } // before completion we inform about it
} ( )
<- done // waiting for the completion of the gorutina
}
func main ( ) {Now, when a channel is transmitted like this, it will be converted to a write-only channel. But below, the channel still remains bidirectional. In principle, the channel can be converted to one-way and without passing it by argument:
done : = make ( chan struct { } )
go func ( done chan <- struct { } ) {
// stuff
done <- struct { } { } // before completion we inform about it
} ( done )
<- done // waiting for the completion of the gorutina
}
done : = make ( chan struct { } )With frequent need, you can make a function that will do all this. Here is an example at play.golang.org . All this allows you to catch some errors at the compilation stage.
writingChan : = ( chan <- struct { } ) ( done ) // the first brackets are not important
readingChan : = ( <- chan struct { } ) ( done ) // the first brackets are required
runtime.LockOSThread()
function allows you to freeze the current gorutin to the current thread. If you call it during initialization (in the init
function), then this will be the main thread of the OS (main OS thread). At the same time, the other gorutinas can easily run in parallel threads of the OS.package main
import (
fmt
"runtime"
)
func init ( ) {
runtime. LockOSThread ( ) // freezes the current gorutin to the current thread
}
func main ( ) {
/ *
communications
* /
done : = make ( chan struct { } ) // <- stop and exit
stuff : = make ( chan func ( ) ) // <- sending functions to the main thread
/ *
create a second thread (in this case, the second mountain, but this is not important)
and start sending "work" to the first
* /
go func ( done chan <- struct { } , stuff chan <- func ( ) ) { // parallel work
stuff <- func ( ) { // first went
fmt. Println ( "1" )
}
stuff <- func ( ) { // the second one went
fmt. Println ( "2" )
}
stuff <- func ( ) { // the third one went
fmt. Println ( "3" )
}
done <- struct { } { }
} ( done, stuff )
Loop :
for {
select {
case do : = <- stuff : // getting "work"
do ( ) // and execution
case <- done :
break loop
}
}
}
package main
import "os"
func main ( ) {
/ *
communications
* /
stop : = make ( chan struct { } ) // needed to stop writing gorutiny
done : = make ( chan struct { } ) // wait for it to complete
write : = make ( chan [ ] byte ) // data to write
/ *
parallel flow for IO operations
* /
go func ( write <- chan [ ] byte , stop <- chan struct { } , done chan <- struct { } ) {
Loop :
for {
select {
case msg : = <- write : // receiving a message for writing
os. Stdout . Write ( msg ) // asynchronous write
case <- stop :
break loop
}
}
done <- struct { } { }
} ( write, stop, done )
write <- [ ] byte ( "Hello" ) // sending messages
write <- [ ] byte ( "World! \ n " ) // write
stop <- struct { } { } // stop
<- done // waiting for completion
}
Source: https://habr.com/ru/post/267785/
All Articles