golang [频道]频道的使用#channel

[频道]频道的用法

1_channel_wait.go
//使用通道同步goroutine
func printNumbers(w chan bool) {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Microsecond)
		fmt.Printf("%d ", i)
	}
	w <- true
}

func printLetters(w chan bool) {
	for i := 'A'; i < 'A'+10; i++ {
		time.Sleep(1 * time.Microsecond)
		fmt.Printf("%c ", i)
	}
	w <- true
}

func main() {
	w1, w2 := make(chan bool), make(chan bool)
	go printNumbers(w1)
	go printLetters(w2)
	<-w1
	<-w2
}
2_channel_message.go
//使用通道实现消息传递
func thrower(c chan int) {
	for i := 0; i < 5; i++ {
		c <- i
		fmt.Println("Threw  >>", i)
	}
}

func catcher(c chan int) {
	for i := 0; i < 5; i++ {
		num := <-c
		fmt.Println("Caught <<", num)
	}
}

func main() {
	c := make(chan int, 3)
	go thrower(c)
	go catcher(c)
	time.Sleep(100 * time.Millisecond)
}
3_channel_select.go
//用关闭通道的方式避免死锁
func callerA(c chan string) {
	c <- "Hello World!"
	close(c)
}

func callerB(c chan string) {
	c <- "Hola Mundo!"
	close(c)
}

func main() {
	a, b := make(chan string), make(chan string)
	go callerA(a)
	go callerB(b)
	var msg string
	openA, openB := true, true
	for openA || openB {
		select {
		case msg, openA = <-a:
			if openA {
				fmt.Printf("%s from A\n", msg)
			}			
		case msg, openB = <-b:
			if openB {
				fmt.Printf("%s from B\n", msg)
			}			
		}
	}
}

golang 够程

[goroutine] goroutine的用法

1_goroutine.go
func printNumbers1() {
	for i := 0; i < 10; i++ {
		// fmt.Printf("%d ", i)
	}
}

func printLetters1() {
	for i := 'A'; i < 'A'+10; i++ {
		// fmt.Printf("%c ", i)
	}
}

func printNumbers2() {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Microsecond)
		// fmt.Printf("%d ", i)
	}
}

func printLetters2() {
	for i := 'A'; i < 'A'+10; i++ {
		time.Sleep(1 * time.Microsecond)
		// fmt.Printf("%c ", i)
	}
}

func print1() {
	printNumbers1()
	printLetters1()
}

func goPrint1() {
	go printNumbers1()
	go printLetters1()	
}

func print2() {
	printNumbers2()
	printLetters2()
}

func goPrint2() {
	go printNumbers2()
	go printLetters2()
}

func main() {
}
2_goroutine_test.go
//go test -v
func TestPrint1(t *testing.T) {
	print1()
}

// run with goroutines
func TestGoPrint1(t *testing.T) {
	goPrint1()
	time.Sleep(1 * time.Millisecond)
}

// run with goroutines and some work
func TestGoPrint2(t *testing.T) {
	goPrint2()
	time.Sleep(1 * time.Millisecond)
}

// Benchmark cases
// go test -run x -bench . -cpu 1
// go test -run x -bench . -cpu 2
func BenchmarkPrint1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		print1()
	}
}

// run with goroutines
func BenchmarkGoPrint1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		goPrint1()
	}
}

// run with some work
func BenchmarkPrint2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		print2()
	}
}

// run with goroutines and some work
func BenchmarkGoPrint2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		goPrint2()
	}
}
3_goroutine_waitGroup.go
//使用waitgroup等待goroutine
func printNumbers2(wg *sync.WaitGroup) {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Microsecond)
		fmt.Printf("%d ", i)
	}
	wg.Done()
}

func printLetters2(wg *sync.WaitGroup) {
	for i := 'A'; i < 'A'+10; i++ {
		time.Sleep(1 * time.Microsecond)
		fmt.Printf("%c ", i)
	}
	wg.Done()
}

func main() {
	var wg sync.WaitGroup
	wg.Add(2)
	go printNumbers2(&wg)
	go printLetters2(&wg)
	wg.Wait()
}

golang 去例行检查测试

go_routine_check.go
func waitTillTableHasCount(conn sqlbuilder.Database, table string, n int) error {
	timeout := time.After(5 * time.Second)
	for {
		select {
		case <-timeout:
			count, err := conn.Collection(table).Find().Count()
			if err != nil {
				return err
			}
			return fmt.Errorf(
				"timeout occurred while waiting for table: %s to have expected: %d rows, but got: %d rows",
				table,
				n,
				int(count),
			)
		case <-time.After(10 * time.Millisecond):
			count, err := conn.Collection(table).Find().Count()
			if err == nil && int(count) == n {
				return nil
			}
		}
	}
}

golang 制作地图类型Go in Go

制作地图类型Go in Go

map_types.go
package main

import "fmt"

func main() {
	ages := map[string]int{
		"Peterson": 52,
		"Sally":    22,
		"Javovia":  15,
		"Ben":      42,
	}

	jobAssociation := make(map[string]string)
	jobAssociation["Peterson"] = "Engineer"
	jobAssociation["Sally"] = "CEO"
	jobAssociation["Jovovia"] = "Gamer"
	jobAssociation["Ben"] = "Programmer"

	printAges(ages)
	printJobAssociations(jobAssociation)

	fmt.Println(ages)
	fmt.Println(jobAssociation)
	fmt.Println(jobAssociation["Jovovia"])
	fmt.Println(jobAssociation["Frank"]) // Blank! :o
	fmt.Println(ages["Sally"])

	delete(ages, "Sally")

	fmt.Println(ages)
	fmt.Println(ages["Sally"])

	delete(jobAssociation, "Jovovia")

	fmt.Println(jobAssociation)
	fmt.Println(jobAssociation["Jovovia"]) // Blank.

	ages2 := map[string]int{
		"Frank":     52,
		"Johnson":   22,
		"Smith":     15,
		"Jezebelle": 42,
	}

	ages3 := map[string]int{
		"Frank":     52,
		"Johnson":   22,
		"Smith":     15,
		"Jezebelle": 42,
	}

	if equal(ages, ages2) {
		fmt.Println("Naw, not really equal.")
	} else {
		fmt.Println("This is correct, not equal.")
	}

	if equal(ages2, ages3) {
		fmt.Println("True, these are effectively the same map values and keys.")
	}
}

func printJobAssociations(associations map[string]string) {
	for name, job := range associations {
		fmt.Printf("%s\t%s\n", name, job)
	}
}

func printAges(ages map[string]int) {
	for name, age := range ages {
		fmt.Printf("%s\t%d\n", name, age)
	}
}

func equal(x, y map[string]int) bool {
	if len(x) != len(y) {
		return false
	}
	for k, xv := range x {
		if yv, ok := y[k]; !ok || yv != xv {
			return false
		}
	}
	return true
}

golang 学习关于去符文和黑客攻击一些例子。

学习关于去符文和黑客攻击一些例子。

main.go
... the rest of the main.go file is here...


  var runes []rune
	for _, r := range "Language: 走" {
		runes = append(runes, r)
	}
	fmt.Printf("%q \n", runes)

	var x, y []int
	for i := 0; i < 10; i++ {
		y = appendInt(x, i)
		fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y)
		x = y
	}

}

func appendInt(x []int, i int) []int {
	var z []int
	zlen := len(x) + 1
	if zlen <= cap(x) {
		z = x[:zlen]
	} else {
		zcap := zlen
		if zcap < 2* len(x) {
			zcap = 2 * len(x)
		}
		z = make([]int, zlen, zcap)
		copy(z, x)
	}

	return z
}

golang 月份

月份

the_months.go
months := [...]string{1: "January", 2:"February", 3: "March", 4:"April", 12:"December"}

for _, s := range months {
	fmt.Printf("The month: %s\n", s)
}

var runes []rune
for _, r := range "Language: 走" {
	runes = append(runes, r)
}
fmt.Printf("%q \n", runes)

var x, y []int
for i := 0; i < 10; i++ {
	y = appendInt(x, i)
	fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y)
	x = y
}

golang 尝试复合类型

尝试复合类型

testing-out-composite-types.go
fmt.Println("Hello, let's talk composite types.")

basketOfStuff := [3]string{"The first string","second","This string."}
var zeeValues [2]int

for i, v := range basketOfStuff {
	fmt.Printf("Value %d: %s\n", i, v)
}

fmt.Println(zeeValues)

if zeeValues[0] == zeeValues[1] {
	fmt.Println("The values are the same, this doesn't instantiate like the `new` keyword.")
} else {
	fmt.Println("The way go appears to instantiate unset variable values, such as in this array is like the `new` keyword instantiation.")
}

zeeValues[0] = 1 + 52 * 3
zeeValues[1] = 9

fmt.Println(zeeValues[len(zeeValues) - 1])

golang 创建货币类型

创建货币类型

currency.go
type Currency int

const (
	USD Currency = iota
	CAN
	EUR
	GBP
	JPY
	NOK
	SEK
	DKK
)

symbol := [...]string{USD: "$", CAN: "$",  EUR: "€", GBP: "£", JPY:"¥", NOK:"kr", SEK:"kr",DKK:"kr"}

fmt.Println(EUR, symbol[EUR])

fmt.Println(JPY, symbol[JPY])

r := [...]int{99: -1}

r[36] = 425
r[42] = 42

fmt.Println(r[36] + r[42])
fmt.Println(strconv.Itoa(r[36]))

golang logrus_logger

logrus_logger.go
package log

import (
	"fmt"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	"github.com/sirupsen/logrus"
	"github.com/project/config"
	"os"
	"runtime"
	"strings"
	"time"
)

var Logger *logrus.Logger
var format = &logrus.JSONFormatter{
	CallerPrettyfier: func(f *runtime.Frame) (function string, file string) {
		goPath := strings.Split(os.Getenv("GOPATH"), ":")[0]
		apiPath := fmt.Sprintf("%s/src/github.com/project/", goPath)
		funcName := strings.Replace(f.Function, "github.com/project/", "", -1)
		filename := strings.Replace(f.File, apiPath, "", -1)
		return fmt.Sprintf("%s()", funcName), fmt.Sprintf("%s:%d", filename, f.Line)
	},
}

func InitLogger(cfg config.ServerConfig) {
	lv, err := logrus.ParseLevel(cfg.LogLevel)
	if err != nil {
		lv = logrus.DebugLevel
	}
	defaultHook := &DefaultFieldHook{}
	lfsHook := newLfsHook(cfg.LogPath, cfg.LogLink)

	logrus.SetReportCaller(true)
	logrus.SetFormatter(format)
	logrus.AddHook(defaultHook)
	logrus.AddHook(lfsHook)
	logrus.SetLevel(lv)
	logrus.SetFormatter(format)

	Logger = logrus.New()
	Logger.SetReportCaller(true)
	Logger.SetFormatter(format)
	Logger.AddHook(defaultHook)
	Logger.AddHook(lfsHook)
	Logger.SetLevel(lv)
	Logger.SetFormatter(format)

}

func newLfsHook(path, link string) logrus.Hook {
	writer, err := rotatelogs.New(
		path+".%Y%m%d",
		rotatelogs.WithLinkName(link),
		rotatelogs.WithRotationTime(time.Hour*24),
		//rotatelogs.WithMaxAge(time.Hour*24*30),
		//rotatelogs.WithRotationCount(maxRemainCnt),
	)
	if err != nil {
		panic(err)
	}
	lfsHook := lfshook.NewHook(lfshook.WriterMap{
		logrus.DebugLevel: writer,
		logrus.InfoLevel:  writer,
		logrus.WarnLevel:  writer,
		logrus.ErrorLevel: writer,
		logrus.FatalLevel: writer,
		logrus.PanicLevel: writer,
	}, format)
	return lfsHook
}

type DefaultFieldHook struct {
}

func (hook *DefaultFieldHook) Levels() []logrus.Level {
	return logrus.AllLevels

}

func (hook *DefaultFieldHook) Fire(entry *logrus.Entry) error {
	entry.Data["appName"] = "api"
	return nil
}

golang redis_stream_go

main.go
package main

import (
	"mytest/stream/consumer"
	"mytest/stream/publisher"
	"mytest/stream/redis"
	"time"
)

func main() {
	redis.Init()
	defer redis.Client.Close()
	go consumer.Consum("1")
	go consumer.Consum("2")
	go consumer.Consum("3")
	//publisher.Publish()
	for i := 0; i < 10; i++ {
		publisher.Publish()
		time.Sleep(2 * time.Second)
	}
	time.Sleep(time.Second * 3)
}
publisher.go
package publisher

import (
	"github.com/go-redis/redis"
	r2"mytest/stream/redis"
)

func Publish() {
	args := redis.XAddArgs{
		Stream:       "codehole",
		MaxLen:       0,
		MaxLenApprox: 0,
		ID:           "*",
		Values:       map[string]interface{}{"name": "laoqian", "age": 30},
	}
	r2.Client.XAdd(&args)
}
consumer.go
package consumer

import (
	"fmt"
	"github.com/go-redis/redis"
	r2 "mytest/stream/redis"
	"time"
)

func Consum(group string) {

	//s, err := r2.Client.XGroupCreate("codehole", group, "$").Result()
	//fmt.Println(s, err)
	for {
		streams, err := r2.Client.XReadGroup(&redis.XReadGroupArgs{
			Group:    group,
			Consumer: "c1",
			Streams:  []string{"codehole", ">"},
			Count:    1,
			Block:    time.Second * 1,
			NoAck:    true,
		}).Result()
		fmt.Println("group:"+group, streams, err)

	}
}
client.go
package redis

import (
	"fmt"
	"github.com/go-redis/redis"
)

var Client *redis.Client

func Init() {
	Client = redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})
	fmt.Println("Redis----------Ping()----------", Client.Ping())
}