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 目的端口 hello

2.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 main

import (
	"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 main

import (
	"fmt"
	"sync"
	"time"
)

var mutex sync.Mutex

var 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() {
	<-pipeline
	printWord("222222222222222222")
}

2.7.6.2 互斥锁(管道)

package main

import (
	"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() {
	<-pipeline
	printWord("222222222222222222")
}


2.7.6.3 读写锁

package main

import (
	"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 = wnum
		fmt.Printf("读 %d==> %d\n", idw, wnum)
		time.Sleep(time.Microsecond * 300)
		rwMutes.Unlock() //

	}

}

//读
func readWord(idx int) {

	for {
		rwMutes.RLock()
		rnum := value
		fmt.Printf("写 %d==>%d\n", idx, rnum)
		rwMutes.RUnlock()
		time.Sleep(time.Millisecond * 300)

	}

}

2.7.6.4 读写锁管道

package main

import (
	"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<-wnum

		fmt.Printf("读 %d==> %d\n", idw, wnum)
		time.Sleep(time.Microsecond * 300)


	}

}

//读
func readWord(re <-chan int,idx int) {

	for {

		rnum := <-re
		fmt.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 main

import (
	"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:=<-in
		fmt.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<-num
		fmt.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) //创建用于结束通信的channel

	product := 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.DB

func connectionSql(){
	//cannot find package "github.com/go-sql-driver/mysql" in any of:
	//idea 配置  file settinf  go  配置goPath
	var err error
	db,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语言函数中有三个点...表示为可变参数,可以接受任意个数的参数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值