专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询
生活随笔
收集整理的這篇文章主要介紹了
专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2.7.5
2.7.5.1 協議通信過程
應用層 hello 傳輸層(udp tcp) 源port 目的端口 hello 網絡層(ip) 源ip 目的ip 源port 目的端口 hello 鏈路層(mac) 源mac 目的mac 源ip 目的ip 源port 目的端口 hello2.7.5.2 tcp傳輸(服務端)
//傳輸端 func main() {listener, err := net.Listen("tcp", "127.0.0.1:8000")if err != nil {fmt.Println("err = ", err)return}defer listener.Close()//阻塞等待用戶連接for {conn, _ := listener.Accept()//接受請求buf := make([]byte, 1024)n, _ := conn.Read(buf)//buf[:n] n有多少打印多少 長度是1024所以不可以打印全部fmt.Println("puf :", string(buf[:n]))conn.Close()}}2.7.5.3 tcp傳輸(客戶端)
// tcp客戶端 package mainimport ("net" )func main() {conn, _ := net.Dial("tcp", "127.0.0.1:8000")defer conn.Close()//發送數據conn.Write([]byte("are you ok?"))}2.7.6鎖
1.讀時共享,寫時獨享 寫鎖優先級比讀鎖高
2.7.6.1 互斥鎖
package mainimport ("fmt""sync""time" )var mutex sync.Mutexvar pipeline = make(chan int)func printWord(word string) {mutex.Lock()for _, value := range word {fmt.Printf("%c",value)time.Sleep(time.Microsecond*1000)}mutex.Unlock() } func main() {go person1()go person2()for {;} } func person1() {printWord("1111111111111111111")pipeline<-666 }func person2() {<-pipelineprintWord("222222222222222222") }2.7.6.2 互斥鎖(管道)
package mainimport ("fmt""time" )var pipeline = make(chan int)func printWord(word string) {for _, value := range word {fmt.Printf("%c",value)time.Sleep(time.Microsecond*1000)}}func main() {go person1()go person2()for {;} } func person1() {printWord("1111111111111111111")pipeline<-666 }func person2() {<-pipelineprintWord("222222222222222222") }2.7.6.3 讀寫鎖
package mainimport ("fmt""math/rand""sync""time" )var rwMutes sync.RWMutex //鎖只有一把 兩個屬性var value int //定義全局變量func main() {//播種隨機數種子rand.Seed(time.Now().UnixNano())for i := 0; i < 5; i++ {go readWord(i + 1)}for i := 0; i < 5; i++ {go writeWord(i + 1)}for {;}}//寫 func writeWord(idw int) {for {wnum := rand.Intn(1000)rwMutes.Lock() //以寫模式加鎖value = wnumfmt.Printf("讀 %d==> %d\n", idw, wnum)time.Sleep(time.Microsecond * 300)rwMutes.Unlock() //}}//讀 func readWord(idx int) {for {rwMutes.RLock()rnum := valuefmt.Printf("寫 %d==>%d\n", idx, rnum)rwMutes.RUnlock()time.Sleep(time.Millisecond * 300)}}2.7.6.4 讀寫鎖管道
package mainimport ("fmt""math/rand""sync""time" )var rwMutes sync.RWMutex //鎖只有一把 兩個屬性var value int //定義全局變量//寫 func writeWord(in chan<- int,idw int) {for {wnum := rand.Intn(1000)in<-wnumfmt.Printf("讀 %d==> %d\n", idw, wnum)time.Sleep(time.Microsecond * 300)}}//讀 func readWord(re <-chan int,idx int) {for {rnum := <-refmt.Printf("寫 %d==>%d\n", idx, rnum)time.Sleep(time.Millisecond * 300)}} func main() {//播種隨機數種子rand.Seed(time.Now().UnixNano())ch1 :=make(chan int)for i := 0; i < 5; i++ {go readWord(i + 1,ch1)}for i := 0; i < 5; i++ {go writeWord(i + 1,ch1)}for {;}}2.7.6.5條件變量鎖
package mainimport ("fmt""math/rand""sync""time" )var cond sync.Cond //創建全局條件變量func consumer(in <-chan int, idx int) {for{cond.L.Lock()//條件變量對應互斥鎖枷鎖for len(in) ==0 { //產品區空 等待生產cond.Wait() //掛起當前攜程,等待全局變量滿足}num:=<-infmt.Printf("%d 消費者消費數據 %d,公共區剩余%d個數據\n",idx,num,len(in))cond.L.Unlock() //生產結束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費者time.Sleep(time.Second)//生產完休息一會,}}func producer(out chan<- int, idx int) {for{cond.L.Lock() //條件變量對應互斥鎖枷鎖//產品區滿 等待消費者消費for len(out)==3{cond.Wait() //掛起當前攜程,等待全局變量滿足}num := rand.Intn(1000)out<-numfmt.Printf("%d 生產者生產數據 %d,公共區剩余%d個數據\n",idx,num,len(out))cond.L.Unlock() //生產結束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費者time.Sleep(time.Second)//生產完休息一會,給其他協程執行機會}} func main() {rand.Seed(time.Now().UnixNano())//設置隨機數種子quit := make(chan bool) //創建用于結束通信的channelproduct := make(chan int, 3) //產品區(公共區)使用channel模擬cond.L = new(sync.Mutex)//創建互斥鎖和條件變量for i :=0;i<1 ;i++ {go producer(product,i+1) //5個生產者}for i :=0;i<1 ;i++ {go consumer(product,i+1) //三個消費者}<-quit //主線程阻塞 不結束 }3.連接mysql
3.1 配置環境變量
3.1.1 設置環境變量 GOPATH
GOPATH D:\goCode //項目的安裝路徑3.1.2 安裝驅動
go get github.com/go-sql-driver/mysql cmd中打開 這行命令會從github同步代碼,同步到GOPATH環境變量下3.1.3 連接數據庫
import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql") var db *sql.DBfunc connectionSql(){//cannot find package "github.com/go-sql-driver/mysql" in any of://idea 配置 file settinf go 配置goPathvar err errordb,err = sql.Open("mysql","root:root@tcp(127.0.0.1:3306)/sxjl?charset=utf8");//defer db.Close()if err != nil{fmt.Printf("connect mysql fail ! [%s]",err)} }3.1.4 查詢
/** 查詢sql*/ func querySql(sql string){rows, err := db.Query(sql)if err != nil{fmt.Printf(" mysql fail resion! [%s]",err)}//https://blog.csdn.net/kenkao/article/details/47857795?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase//字典類型//構造scanArgs、values兩個數組,scanArgs的每個值指向values相應值的地址columns, _ := rows.Columns()scanArgs := make([]interface{}, len(columns))values := make([]interface{}, len(columns))for i := range values {scanArgs[i] = &values[i]}for rows.Next() {//將行數據保存到record字典err = rows.Scan(scanArgs...)record := make(map[string]string)for i, col := range values {if col != nil {record[columns[i]] = string(col.([]byte))}}fmt.Println(record)}}通用
1.fmt.Sprintf (格式化輸出)
%v 按值的本來值輸出%+v 在 %v 的基礎上,對結構體字段名和值進行展開 %#v 輸出 Go 語言語法格式的值%T 輸出 Go 語言語法格式的類型和值%% 輸出 %% 本體%b 整型以二進制方式顯示%o 整型以八進制方式顯示%d 整型以十進制方式顯示%x 整型以 十六進制顯示%X 整型以十六進制、字母大寫方式顯示%U Unicode 字符%f 浮點數%p 指針,十六進制方式顯示2.make 和 new的區別
make 被用來分配引用類型的內存: (make 只能用于 slice,map,channel 三種類型,)new 被用來分配除了引用類型的所有其他類型的內存: int, string, array等3.interface{} 類型
interface{} 類型,空接口 //由于沒有 implements 關鍵字,所以所有類型都至少實現了 0 個方法,所以 所有類型都實現了空接口func PrintAll(vals []interface{}) {for _, val := range vals {fmt.Println(val)}<br> }func main() {names := []string{"stanley", "david", "oscar"}//**********必須將[]string 轉化為 []interface{}vals := make([]interface{}, len(names))for i, v := range names {vals[i] = v}PrintAll(vals) }4.參數后面的三個點
Go語言函數中有三個點...表示為可變參數,可以接受任意個數的參數。 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专科 java转go 翱翔之路(三)开发
- 下一篇: echat 图表动态数据生成,渲染,自定