1. 首页
  2. 主题
  3. Go问与答

请教个select...case...问题,烦恼了好几天了

orthoc · · 1303 次点击
共有两台服务器A跟B,它们使用一条grpc长链接进行交互,A是grpc服务端,在公网;B是客户端,在内网。 服务器A的代码里有两个协程,分别监听http和grpc,用一个同步channel进行通信。 我的业务流程: 1、用户通过http接口访问A,A需要调用B的程序,此时使用Send(*Response) error把必要的参数发送过去; 2、B通过Recv()监听到A发来的请示,把运算结果通过Send()发送回A; 3、A通过Recv()收到运算结果,把结果输入到同步channel,http服务结束同步阻塞,返回http response给用户。 现在我要在步骤1加上30秒超时的限制,却出现了奇怪的问题,伪代码如下: ``` A.Send("data...") go func() { time.Sleep(30e9) timeoutChan <- true }() select { case <-timeoutChan: // 返回超时错误信息 case resp := <-respChan: // 正常返回数据 } ``` 按照我的想法,应该是用户访问A的http接口时,如果超过30秒,会得到个超时错误。但却产生以下问题,有并发请示时(假设恰好请示1和请示2),请示1得到的http response是请示2的运算结果,请示2得到的http response是请示1的运算结果。 我回滚到原代码,(即去掉了超时限制功能,没有上边的go func(){time.Sleep()}和select... case...),只使用同步channel一直阻塞等待返回结果,进行压力测试,并不会出上以上问题,http request跟response都能对应。所以现在想不通,为何select... case...会出现以上问题,我需要做什么改进。
czyt
云在青天水在瓶
对于chan的timeout 参考下面的例子 ```go package main import ( &#34;fmt&#34; &#34;os&#34; &#34;time&#34; ) func main() { notify := make(chan int64, 1) timeoutCnt := 0 go func() { counter := 0 for { time.Sleep(1 * time.Second) notify &lt;- time.Now().UnixNano() counter++ if counter &gt; 30 { break } } }() for { select { case currentTime := &lt;-notify: fmt.Println(currentTime) case &lt;-time.After(5 * time.Second): fmt.Println(&#34;time out&#34;) timeoutCnt++ if timeoutCnt &gt; 3 { os.Exit(0) } } } } ```
#1

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中