专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询
生活随笔
收集整理的這篇文章主要介紹了
专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2.7.5
2.7.5.1 協(xié)議通信過程
應(yīng)用層 hello 傳輸層(udp tcp) 源port 目的端口 hello 網(wǎng)絡(luò)層(ip) 源ip 目的ip 源port 目的端口 hello 鏈路層(mac) 源mac 目的mac 源ip 目的ip 源port 目的端口 hello2.7.5.2 tcp傳輸(服務(wù)端)
//傳輸端 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()//接受請(qǐng)求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()//發(fā)送數(shù)據(jù)conn.Write([]byte("are you ok?"))}2.7.6鎖
1.讀時(shí)共享,寫時(shí)獨(dú)享 寫鎖優(yōu)先級(jí)比讀鎖高
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 //鎖只有一把 兩個(gè)屬性var value int //定義全局變量func main() {//播種隨機(jī)數(shù)種子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 //鎖只有一把 兩個(gè)屬性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() {//播種隨機(jī)數(shù)種子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 //創(chuàng)建全局條件變量func consumer(in <-chan int, idx int) {for{cond.L.Lock()//條件變量對(duì)應(yīng)互斥鎖枷鎖for len(in) ==0 { //產(chǎn)品區(qū)空 等待生產(chǎn)cond.Wait() //掛起當(dāng)前攜程,等待全局變量滿足}num:=<-infmt.Printf("%d 消費(fèi)者消費(fèi)數(shù)據(jù) %d,公共區(qū)剩余%d個(gè)數(shù)據(jù)\n",idx,num,len(in))cond.L.Unlock() //生產(chǎn)結(jié)束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費(fèi)者time.Sleep(time.Second)//生產(chǎn)完休息一會(huì),}}func producer(out chan<- int, idx int) {for{cond.L.Lock() //條件變量對(duì)應(yīng)互斥鎖枷鎖//產(chǎn)品區(qū)滿 等待消費(fèi)者消費(fèi)for len(out)==3{cond.Wait() //掛起當(dāng)前攜程,等待全局變量滿足}num := rand.Intn(1000)out<-numfmt.Printf("%d 生產(chǎn)者生產(chǎn)數(shù)據(jù) %d,公共區(qū)剩余%d個(gè)數(shù)據(jù)\n",idx,num,len(out))cond.L.Unlock() //生產(chǎn)結(jié)束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費(fèi)者time.Sleep(time.Second)//生產(chǎn)完休息一會(huì),給其他協(xié)程執(zhí)行機(jī)會(huì)}} func main() {rand.Seed(time.Now().UnixNano())//設(shè)置隨機(jī)數(shù)種子quit := make(chan bool) //創(chuàng)建用于結(jié)束通信的channelproduct := make(chan int, 3) //產(chǎn)品區(qū)(公共區(qū))使用channel模擬cond.L = new(sync.Mutex)//創(chuàng)建互斥鎖和條件變量for i :=0;i<1 ;i++ {go producer(product,i+1) //5個(gè)生產(chǎn)者}for i :=0;i<1 ;i++ {go consumer(product,i+1) //三個(gè)消費(fèi)者}<-quit //主線程阻塞 不結(jié)束 }3.連接mysql
3.1 配置環(huán)境變量
3.1.1 設(shè)置環(huán)境變量 GOPATH
GOPATH D:\goCode //項(xiàng)目的安裝路徑3.1.2 安裝驅(qū)動(dòng)
go get github.com/go-sql-driver/mysql cmd中打開 這行命令會(huì)從github同步代碼,同步到GOPATH環(huán)境變量下3.1.3 連接數(shù)據(jù)庫
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//字典類型//構(gòu)造scanArgs、values兩個(gè)數(shù)組,scanArgs的每個(gè)值指向values相應(yīng)值的地址columns, _ := rows.Columns()scanArgs := make([]interface{}, len(columns))values := make([]interface{}, len(columns))for i := range values {scanArgs[i] = &values[i]}for rows.Next() {//將行數(shù)據(jù)保存到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 的基礎(chǔ)上,對(duì)結(jié)構(gòu)體字段名和值進(jìn)行展開 %#v 輸出 Go 語言語法格式的值%T 輸出 Go 語言語法格式的類型和值%% 輸出 %% 本體%b 整型以二進(jìn)制方式顯示%o 整型以八進(jìn)制方式顯示%d 整型以十進(jìn)制方式顯示%x 整型以 十六進(jìn)制顯示%X 整型以十六進(jìn)制、字母大寫方式顯示%U Unicode 字符%f 浮點(diǎn)數(shù)%p 指針,十六進(jìn)制方式顯示2.make 和 new的區(qū)別
make 被用來分配引用類型的內(nèi)存: (make 只能用于 slice,map,channel 三種類型,)new 被用來分配除了引用類型的所有其他類型的內(nèi)存: int, string, array等3.interface{} 類型
interface{} 類型,空接口 //由于沒有 implements 關(guān)鍵字,所以所有類型都至少實(shí)現(xiàn)了 0 個(gè)方法,所以 所有類型都實(shí)現(xiàn)了空接口func PrintAll(vals []interface{}) {for _, val := range vals {fmt.Println(val)}<br> }func main() {names := []string{"stanley", "david", "oscar"}//**********必須將[]string 轉(zhuǎn)化為 []interface{}vals := make([]interface{}, len(names))for i, v := range names {vals[i] = v}PrintAll(vals) }4.參數(shù)后面的三個(gè)點(diǎn)
Go語言函數(shù)中有三個(gè)點(diǎn)...表示為可變參數(shù),可以接受任意個(gè)數(shù)的參數(shù)。 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的专科 java转go 翱翔之路(四)协议通信 锁,互斥锁 读写锁 条件变量锁 连接mysql 查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专科 java转go 翱翔之路(三)开发
- 下一篇: Mysql笔记总结