阅读更多
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func Producer(factor int,out chan<- int){
for i:=0;;i++{
out <- i*factor
}
}
func Consumer(in <-chan int){
for v := range in {
fmt.Println(v)
}
}
func main(){
ch:=make(chan int,64)
go Producer(3,ch)
go Producer(5,ch)
go Consumer(ch)
//运行一定时间后退出
time.Sleep(5*time.Second)
// Ctrl+C 退出
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
fmt.Printf("quit (%v)\n", <-sig)
////合建chan
//c := make(chan os.Signal)
////监听指定信号 ctrl+c kill
////signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGUSR1, syscall.SIGUSR2)
//signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
////阻塞直到有信号传入
//fmt.Println("启动")
////阻塞直至有信号传入
//s := <-c
//fmt.Println("退出信号", s)
}
/**************************************************************/
package main
import "fmt"
func main() {
done := make(chan int, 10) // 带 10 个缓存
// 开N个后台打印线程
for i := 0; i < cap(done); i++ {
go func(){
fmt.Println("你好, 世界")
done <- 1
}()
}
// 等待N个后台线程完成
for i := 0; i < cap(done); i++ {
<-done
}
}
/*
wg.Add(1) 用于增加等待事件的个数,必须确保在后台线程启动之前执行
(如果放到后台线程之中执行则不能保证被正常执行到) 。当后台线程完成打印工
作之后,调用 wg.Done() 表示完成一个事件。 main 函数的 wg.Wait() 是等待
全部的事件完成
*/
/*************************************************************/
package main
import (
"fmt"
)
/**
通道变量 会阻塞
当 <-done 执行时,必然要求 done <- 1 也已经执行。根据同一个Gorouine依然
满足顺序一致性规则,我们可以判断当 done <- 1 执行时, println("你好, 世
界") 语句必然已经执行完成了。因此,现在的程序确保可以正常打印结果。
*/
func main() {
done := make(chan int)
go func(){
fmt.Println("你好, 世界")
done <- 1
}()
<-done
}
//func main() {
// var mu sync.Mutex
// mu.Lock()
// go func(){
// println("你好, 世界")
// mu.Unlock()
// }()
// mu.Lock()
//}
//可以确定后台线程的 mu.Unlock() 必然在 println("你好, 世界") 完成后发生
//(同一个线程满足顺序一致性) , main 函数的第二个 mu.Lock() 必然在后台线
//程的 mu.Unlock() 之后发生 ( ,当第二次加锁时会因为锁已经被占用(不是递归锁) 而阻塞)( sync.Mutex 保证) ,此时后台线程的打印工作已
//经顺利完成了。
/**************************************************************/
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
// 开N个后台打印线程
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
fmt.Println("你好, 世界")
wg.Done()
}()
}
// 等待N个后台线程完成
wg.Wait()
}
/**************************************************************/
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main(){
var ag = [...]string{"test","go","tiandi","健康"}
fmt.Println("len(s):",(*reflect.StringHeader)(unsafe.Pointer(&ag)).Len)
fmt.Printf("b: %T\n", ag) // b: [3]int
fmt.Printf("b: %#v\n", ag)
for i := range ag {
fmt.Printf("a[%d]: %d\n", i, ag[i])
}
//z指针转化
//任何指针都可以转换为unsafe.Pointer
//unsafe.Pointer可以转换为任何指针
//uintptr可以转换为unsafe.Pointer
//unsafe.Pointer可以转换为uintptr
i:= 10
ip:=&i
var fp *float64 = (*float64)(unsafe.Pointer(ip))
*fp = *fp * 3
fmt.Println(i)
}
/**************************************************************/
package main
import (
"sync"
"sync/atomic"
"fmt"
"sync/mutex"
)
func main(){
var s =Instance()
s.Kt();
fmt.Printf("\n %+v",s)
fmt.Printf("\n %v",s)
}
type singleton struct {}
var (
instance *singleton
initialized uint32
mu sync.Mutex
)
func Instance() *singleton {
if atomic.LoadUint32(&initialized) == 1 {
return instance
}
mu.Lock()
defer mu.Unlock()
if instance == nil {
defer atomic.StoreUint32(&initialized, 1)
instance = &singleton{}
}
return instance
}
func (*singleton) Kt() {
var a = []int{1,2,3,4}
for j,y := range a {
fmt.Printf("\nj,y : %d-%d",j,y)
}
}
/**************************************************************/
package main
import (
"fmt"
"os"
"strings"
)
type UpperString string
func (s UpperString) String() string {
return strings.ToUpper(string(s))
}
/*defer 语句延迟执行了一个匿名函数,因为这个匿名函数捕获了外部函数的
局部变量 v ,这种函数我们一般叫闭包。闭包对捕获的外部变量并不是传值方式
访问,而是以引用的方式访问*/
func main(){
fmt.Fprintln(os.Stdout, UpperString("hello, world"))
k := Inc()
fmt.Printf("\nK: %d",k)
for i := 0; i < 3; i++ {
defer func(){ fmt.Printf( "1111 %d\n ",i) } ()
}
for i := 0; i < 3; i++ {
i := i // 定义一个循环体内局部变量i
defer func(){ fmt.Printf( "2222 %d\n ",i) } ()
}
for i := 0; i < 3; i++ {
// 通过函数传入i
// defer 语句会马上对调用参数求值
defer func(i int){ fmt.Printf( "3333 %d\n ",i) } (i)
}
}
func Inc() (v int) {
defer func(){
v++
fmt.Printf("%d",v)
} ()
return 42
}