• 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 ...
    ", 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         // 从标准输入设备中读取以 
     为结尾的一行
    30         input, _ := inputReader.ReadString('
    ')
    31         // 去掉读到数据的换行和回车
    32         trimmedInput := strings.Trim(input, "
    ")
    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 )

  • 相关阅读:
    怎么做程序?(摘录微博)
    ObjectiveC protocol & delegate
    iPhone网络编程之监视网络连接
    第二个iPhone应用程序:“Say Hello”
    NSNotificationCenter 的使用详解
    打字效果,自动换行的CCLabelTTF
    objectc's selector (forward)
    IOS触摸事件
    如何使用Android SDK Manager下载 SDK
    年月日三级级联
  • 原文地址:https://www.cnblogs.com/Crixus3714/p/10399645.html
Copyright © 2020-2023  润新知