V1.0
package main
import (
"fmt"
"time"
)
func loopcheck(ch chan bool) {
var i int = 0
for {
time.Sleep(time.Second)
i++
if i == int(2) {
ch <- true
}
}
}
func main() {
ch := make(chan bool)
go loopcheck(ch)
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case b := <-ch:
fmt.Println("中断收到啦!", b)
case <-t.C:
fmt.Println("main")
}
}
}
可以但是有个任务没有停止!
V2
package main
import (
"fmt"
"time"
)
func loopcheck(ch chan bool) {
var i int = 0
if ch == nil {
fmt.Println("loopcheck die")
time.Sleep(time.Second)
return
}
for {
time.Sleep(time.Second)
i++
if i == int(2) {
ch <- true
}
}
}
func main() {
ch := make(chan bool)
go loopcheck(ch)
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case b := <-ch:
fmt.Println("中断收到啦!", b)
close(ch)
case <-t.C:
fmt.Println("main")
}
}
}
他的测试是
[Running] go run "c:\Users\Koson.Gong\Desktop\sgo\my\myselfkill.go"
main
main
中断收到啦! true
中断收到啦! false
panic: close of closed channel
goroutine 1 [running]:
main.main()
c:/Users/Koson.Gong/Desktop/sgo/my/myselfkill.go:32 +0x17a
exit status 2
所以我没有必要去关闭了 因为他已经关闭了 !
怎么会关闭的呢? 奇怪啊
V3用这个把
package main
import (
"fmt"
"time"
)
func loopcheck(ch chan bool) {
var i int = 0
/*
这个办法C风格太强 不好 使用Go风格的
*/
/*
for {
time.Sleep(800 * time.Millisecond)
i++
if i == int(2) {
//close(ch)
ch <- true
return
}
}
*/
ticker_period := 800 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case <-t.C:
i++
fmt.Println(i)
if i == int(2) {
//close(ch)
ch <- true
return //自动消亡这个协程
}
}
}
}
func main() {
ch := make(chan bool)
go loopcheck(ch)
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case b := <-ch:
fmt.Println("中断收到啦!", b)
case <-t.C:
fmt.Println("main")
}
}
}
遗留问题 即时 谁关闭的?
package main
import (
"fmt"
"time"
)
func loopcheck(ch chan bool) {
var cnt int = 0
ticker_period := 800 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case <-t.C:
fmt.Println(cnt)
cnt++
if cnt == 3 {
//close(ch)
ch <- true
}
}
}
}
func main() {
ch := make(chan bool, 2)
go loopcheck(ch)
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
//case b := <-ch:
// fmt.Println("中断收到啦!", b)
case <-ch:
if x, ok := <-ch; ok {
fmt.Println("中断收到啦!", x)
}
case <-t.C:
fmt.Println("main")//这个代码测试有问题 前面的case会把后面的case抢占
}
}
}
带着这个问题 学习TingGo的SCAN
先看MUKA的
package api
import "github.com/muka/go-bluetooth/bluez/profile/adapter"
func Discover(a *adapter.Adapter1, filter *adapter.DiscoveryFilter,)//参数
(chan *adapter.DeviceDiscovered, func(), error) {//返回值 看后图
a.SetPairable(false)//操作参数1 adapter
a.SetDiscoverable(false)//操作参数1 adapter 所以不能主从一体了吗?
a.SetPowered(true)//操作参数1 adapter
filterMap := make(map[string]interface{})
if filter != nil {//操作参数2 万能过滤器 自己去转化ToMap
filterMap = filter.ToMap()
}
a.SetDiscoveryFilter(filterMap)//操作参数1
a.StartDiscovery()//操作参数1
ch, discoveryCancel, err := a.OnDeviceDiscovered()
cancel := func() {
a.StopDiscovery()
discoveryCancel()
}
return ch, cancel, nil
/*
返回结果1--是ch--------它来自a.OnDeviceDiscovered 所以OnDeviceDiscovered是关键
返回结果2--是一个函数---你调用它就是调用了i-a.StopDiscovery II-discoveryCancel
*/
}
自己写小程序 效果一样 重复关闭
package main
import (
"fmt"
"time"
)
func loopcheck() (chan bool, func()) {
ch := make(chan bool)
go func() {
var i int = 0
for {
time.Sleep(time.Second)
i++
if i == int(3) {
ch <- true
}
}
}()
cancel := func() {
close(ch)
}
return ch, cancel
}
func main() {
c, fun := loopcheck()
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case b := <-c:
fmt.Println("中断收到啦!", b)
fun()
case <-t.C:
fmt.Println("main")
}
}
}
scan是怎么做的
这个 怎么写一个毒杀函数
package main
import (
"fmt"
"time"
)
type Adapter struct {
cancelChan chan struct{}
num int
}
func (a *Adapter) Scan(callback func(*Adapter)) bool {
if a.cancelChan != nil {
fmt.Println("ERR Scan")
return false
}
/*
程序进来的时候 通道 a.cancelChan 必须是关闭的
因为我马上回给他重写分配内存的
通道是谁关闭的?是用户自己再外面回调关闭的
*/
cancelChan := make(chan struct{})
a.cancelChan = cancelChan
for {
a.num++
time.Sleep(time.Second)
fmt.Println(a.num)
if a.num%int(3) == 0 {
fmt.Println("条件何时 扫到东西 执行一次")
callback(a)
}
}
}
func (a *Adapter) StopScan() bool {
if a.cancelChan == nil {
fmt.Println("ERR StopScan")
return false
}
close(a.cancelChan)
a.cancelChan = nil
fmt.Println("StopScan")
return true
}
func main() {
var A Adapter = Adapter{num: 0}
A.Scan(
func(B *Adapter) {
fmt.Println("B.num", B.num)
if B.num == int(6) {
B.StopScan()
}
})
for {
}
}
/*
Koson.Gong@MC2077 MINGW64 ~/Desktop/sgo/my (master)
$ go build myscan.go
Koson.Gong@MC2077 MINGW64 ~/Desktop/sgo/my (master)
$ ./myscan.exe
1
2
3
条件何时 扫到东西 执行一次
B.num 3
4
5
6
条件何时 扫到东西 执行一次
B.num 6
StopScan
7
8
9
条件何时 扫到东西 执行一次
B.num 9
10
*/
修改 也不行
package main
import (
"fmt"
"time"
)
type Adapter struct {
cancelChan chan struct{}
num int
}
func (a *Adapter) Scan(callback func(*Adapter)) bool {
if a.cancelChan != nil {
fmt.Println("ERR Scan")
return false
}
/*
程序进来的时候 通道 a.cancelChan 必须是关闭的
因为我马上回给他重写分配内存的
通道是谁关闭的?是用户自己再外面回调关闭的
*/
cancelChan := make(chan struct{})
a.cancelChan = cancelChan
go func() {
for {
a.num++
time.Sleep(time.Second)
fmt.Println(a.num)
if a.num%int(3) == 0 {
fmt.Println("条件何时 扫到东西 执行一次")
callback(a)
}
}
}()
for {
select {
case <-cancelChan:
fmt.Println("--- OUT ---")
return true
}
}
}
func (a *Adapter) StopScan() bool {
if a.cancelChan == nil {
fmt.Println("ERR StopScan")
return false
}
close(a.cancelChan)
a.cancelChan = nil
fmt.Println("StopScan")
return true
}
func main() {
var A Adapter = Adapter{num: 0}
A.Scan(
func(B *Adapter) {
fmt.Println("B.num", B.num)
if B.num == int(6) {
B.StopScan()
}
})
for {
}
}
/*
Koson.Gong@MC2077 MINGW64 ~/Desktop/sgo/my (master)
$ go build myscan.go
Koson.Gong@MC2077 MINGW64 ~/Desktop/sgo/my (master)
$ ./myscan.exe
1
2
3
条件何时 扫到东西 执行一次
B.num 3
4
5
6
条件何时 扫到东西 执行一次
B.num 6
StopScan
7
8
9
条件何时 扫到东西 执行一次
B.num 9
10
*/
不能再里面继续go了!
下面终于成功了!!!
package main
import (
"fmt"
"time"
)
type Adapter struct {
cancelChan chan struct{}
num int
}
func (a *Adapter) Scan(callback func(*Adapter)) bool {
if a.cancelChan != nil {
fmt.Println("ERR Scan")
return false
}
/*
程序进来的时候 通道 a.cancelChan 必须是关闭的
因为我马上回给他重写分配内存的
通道是谁关闭的?是用户自己再外面回调关闭的
*/
cancelChan := make(chan struct{})
a.cancelChan = cancelChan
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
for {
select {
case <-t.C:
a.num++
fmt.Println(a.num)
callback(a)
case <-cancelChan:
fmt.Println("--OUT---")
return true
}
}
}
func (a *Adapter) StopScan() bool {
if a.cancelChan == nil {
fmt.Println("ERR StopScan")
return false
}
close(a.cancelChan)
a.cancelChan = nil
fmt.Println("StopScan")
return true
}
func main() {
var A Adapter = Adapter{num: 0}
A.Scan(
func(B *Adapter) {//这里的B其实也是A 因为调用再Scan里面赋值了A
fmt.Println("B.num", B.num)
if B.num == int(6) {
B.StopScan()
}
})
for {
}
}
可以利用它完成轮询变中断!
比如过一段时间 断开连接
package main
import (
"fmt"
"time"
)
type BleStatus struct {
cancelChan chan struct{}
isconnected bool
}
func (a *BleStatus) Check(callback func(*BleStatus)) {
if a.cancelChan != nil {
fmt.Println("ERR Scan")
return
}
cancelChan := make(chan struct{})
a.cancelChan = cancelChan
ticker_period := 1000 * time.Millisecond
t := time.NewTicker(ticker_period)
var num int = 0
for {
select {
case <-t.C:
num++
fmt.Println(num)
if num == 3 {
a.isconnected = false
}
callback(a)
case <-cancelChan:
fmt.Println("--OUT---")
return
}
}
}
func (a *BleStatus) StopCheck() bool {
if a.cancelChan == nil {
fmt.Println("ERR StopCheck")
return false
}
close(a.cancelChan)
a.cancelChan = nil
fmt.Println("StopCheck")
return true
}
func main() {
var A BleStatus = BleStatus{isconnected: true}
A.Check(
func(B *BleStatus) { //这里的B其实也是A 因为调用再Scan里面赋值了A
fmt.Println("B.num", B.isconnected)
if B.isconnected == false {
B.StopCheck()
}
})
fmt.Println("HELLO WORLD")
for {
}
}