Go 基础 03

  • goroutine   channel
 1 package main
 2 
 3 import (
 4     "fmt"
 5     "runtime"
 6 )
 7 
 8 // goroutine 使用 Channel 进行通信
 9 // 计算 1000 以内的素数
10 // 一个 goroutine 写,一个 goroutine 读
11 func calc(taskChan chan int, resChan chan int, exitChan chan bool) {
12     for v := range taskChan {
13         flag := true
14         // 判断 v 是否是素数
15         for i := 2; i < v; i++ {
16             if 0 == v%i {
17                 // 不是素数的 flag
18                 flag = false
19                 break
20             }
21         }
22         if flag {
23             // 是素数的情况,就放到 resChan 的 channel 中
24             resChan <- v
25         }
26     }
27     // 这个协程执行完成后,向 exitChan 的channel 中发送一个完成信号
28     exitChan <- true
29 }
30 
31 func main() {
32 
33     // 获取当前机器 cpu 的核数
34     num := runtime.NumCPU()
35     fmt.Println(num)
36 
37     intChan := make(chan int, 1000)
38     resultChan := make(chan int, 1000)
39     // exitChan 装满后,就表示所有协程都执行完成了
40     exitChan := make(chan bool, num)
41 
42     // 匿名函数方式,启动一个协程
43     go func() {
44         for i := 0; i < 100000; i++ {
45             intChan <- i
46         }
47         // 关闭 Channel
48         close(intChan)
49     }()
50     // 计算 1000 以内的素数
51     // 一个 goroutine 写,一个 goroutine 读
52     // 通过 for 循环,一共启动 4 个协程
53     // 同时从 intChan 中取数字,计算素数
54     for i := 0; i < num; i++ {
55         go calc(intChan, resultChan, exitChan)
56     }
57 
58     // 匿名函数方式,启动一个协程
59     go func() {
60         // 没有完成的 channel 主线程取值时,就阻塞在这里
61         // 直到把 exitChan 都取完,主线程才会继续向下执行
62         for i := 0; i < num; i++ {
63             // 只是取,并不关注取的是什么
64             <-exitChan
65             fmt.Printf("[message] => %d had completed ...\n", i)
66         }
67         // 都取完之后,表示所有的协程都执行完成,就可以关闭 resultChan 的 channel
68         close(resultChan)
69     }()
70 
71     for v := range resultChan {
72         fmt.Println(v)
73     }
74 }
  • 非阻塞方式从 channel 中读取数据
 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 
 8 func main() {
 9     var ch chan int
10     ch = make(chan int, 10)
11     ch2 := make(chan int, 10)
12 
13     // 向 channel 中存放数据
14     go func() {
15         var i int = 1
16         for {
17             ch <- i
18             time.Sleep(time.Second)
19             ch2 <- i * i
20             time.Sleep(time.Second)
21             i++
22         }
23     }()
24 
25     for {
26         // 当 channel 中的数据被取空时,
27         // 不执行阻塞,而进入 default 分支
28         select {
29         case v := <-ch:
30             fmt.Println(v)
31         case v := <-ch2:
32             fmt.Println(v)
33         default:
34             fmt.Println("get data timeout ...")
35             time.Sleep(time.Second)
36         }
37     }
38 }
  • tcp  编程
 1 // server.go
 2 
 3 package main
 4 
 5 import (
 6     "fmt"
 7     "net"
 8 )
 9 
10 func main() {
11     fmt.Println("start server...")
12     listen, err := net.Listen("tcp", "0.0.0.0:50000")
13     if err != nil {
14         fmt.Println("listen failed, err:", err)
15         return
16     }
17     for {
18         conn, err := listen.Accept()
19         if err != nil {
20             fmt.Println("accept failed, err:", err)
21             continue
22         }
23         go process(conn)
24     }
25 }
26 func process(conn net.Conn) {
27     defer conn.Close()
28     for {
29         buf := make([]byte, 512)
30         n, err := conn.Read(buf)
31         if err != nil {
32             fmt.Println("read err:", err)
33             return
34         }
35 
36         fmt.Printf(string(buf[0:n]))
37     }
38 }
 1 // client.go
 2 
 3 package main
 4 
 5 import (
 6     "bufio"
 7     "fmt"
 8     "net"
 9     "os"
10     "strings"
11 )
12 
13 // 客户端的处理流程
14 func main() {
15     // 1- 建立与服务端的连接
16     conn, err := net.Dial("tcp", "localhost:50000")
17     if err != nil {
18         fmt.Println("Error dialing", err.Error())
19         return
20     }
21 
22     // 3- 关闭连接
23     defer conn.Close()
24 
25     // 2- 进行数据收发
26     // 从标准输入设备中读取
27     inputReader := bufio.NewReader(os.Stdin)
28     for {
29         // 从标准输入设备中读取以 \n 为结尾的一行
30         input, _ := inputReader.ReadString('\n')
31         // 去掉读到数据的换行和回车
32         trimmedInput := strings.Trim(input, "\r\n")
33 
34         // 输入 Q 客户端就退出了
35         if trimmedInput == "Q" {
36             return
37         }
38         // 字符串转为字节切片后,向服务端发送
39         _, err = conn.Write([]byte(trimmedInput))
40         if err != nil {
41             return
42         }
43     }
44 }
  • redis  连接池
 1 package main
 2 
 3 import (
 4     "fmt"
 5 
 6     "github.com/garyburd/redigo/redis"
 7 )
 8 
 9 var pool *redis.Pool
10 
11 func init() {
12     pool = &redis.Pool{
13         MaxIdle:     16,
14         MaxActive:   0,
15         IdleTimeout: 300,
16         Dial: func() (redis.Conn, error) {
17             return redis.Dial("tcp", "192.168.56.164:6379")
18         },
19     }
20 }
21 
22 func main() {
23 
24     c := pool.Get()
25     // 方法执行后,关闭 redis.Dial 的连接
26     defer c.Close()
27 
28     _, err := c.Do("Set", "abc", 100)
29     if err != nil {
30         fmt.Println(err)
31         return
32     }
33 
34     r, err := redis.Int(c.Do("Get", "abc"))
35     if err != nil {
36         fmt.Println("get abc failed,", err)
37         return
38     }
39 
40     fmt.Println(r)
41     // 关闭连接池已使用的资源
42     pool.Close()
43 }
  • http 编程
 1 5.    // server.go
 2 
 3 package main
 4 
 5 import (
 6     "fmt"
 7     "net/http"
 8 )
 9 
10 func Hello(w http.ResponseWriter, r *http.Request) {
11     // 向本地打印
12     fmt.Println("handle hello")
13     // 向浏览器端发送数据
14     fmt.Fprintf(w, "hello ")
15 }
16 
17 func login(w http.ResponseWriter, r *http.Request) {
18     fmt.Println("handle login")
19     fmt.Fprintf(w, "login ")
20 }
21 
22 func history(w http.ResponseWriter, r *http.Request) {
23     fmt.Println("handle history")
24     fmt.Fprintf(w, "history ")
25 }
26 
27 // 服务端
28 func main() {
29     // 设置路由,处理根目录
30     http.HandleFunc("/", Hello)
31     http.HandleFunc("/user/login", login)
32     http.HandleFunc("/user/history", history)
33     err := http.ListenAndServe("0.0.0.0:8880", nil)
34     if err != nil {
35         fmt.Println("http listen failed")
36     }
37 }
 1 // client.go
 2 
 3 package main
 4 
 5 import (
 6     "fmt"
 7     "io/ioutil"
 8     "net/http"
 9 )
10 
11 // 客户端访问百度
12 func main() {
13     res, err := http.Get("https://www.baidu.com/")
14     if err != nil {
15         fmt.Println("get err:", err)
16         return
17     }
18 
19     data, err := ioutil.ReadAll(res.Body)
20     if err != nil {
21         fmt.Println("get data err:", err)
22         return
23     }
24 
25     fmt.Println(string(data))
26 }
  • 操作  mysql  数据库
 1 package main
 2 
 3 import (
 4     "fmt"
 5 
 6     _ "github.com/go-sql-driver/mysql"
 7     "github.com/jmoiron/sqlx"
 8 )
 9 
10 type Person struct {
11     // 结构体字段 UserId 对应 数据库中的 字段 user_id
12     UserId   int    `db:"user_id"`
13     Username string `db:"username"`
14     Sex      string `db:"sex"`
15     Email    string `db:"email"`
16 }
17 
18 type Place struct {
19     Country string `db:"country"`
20     City    string `db:"city"`
21     TelCode int    `db:"telcode"`
22 }
23 
24 var Db *sqlx.DB
25 
26 func init() {
27 
28     database, err := sqlx.Open("mysql", "root:123456@tcp(192.168.56.164:3306)/test")
29     if err != nil {
30         fmt.Println("open mysql failed,", err)
31         return
32     }
33 
34     Db = database
35 }
36 
37 func main() {
38 
39     var person []Person
40     // 查询并将结果返回到 person 数组中
41     err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
42     if err != nil {
43         fmt.Println("exec failed, ", err)
44         return
45     }
46 
47     fmt.Println("select succ:", person)
48     fmt.Println("select succ:", person[0])
49 }

 

( Over )

posted @ 2019-02-19 10:45  Crixus3714  阅读(114)  评论(0编辑  收藏  举报