2017-08-01 23 views
0

我想知道如果interruptable_call是不中斷的,並且在上下文完成後返回會發生什麼。調用堆棧已經被破壞。退貨行爲將執行什麼? select如何在一個案例返回而另一個案件仍在運行的情況下執行。這種情況下的函數調用會被終止嗎?以什麼方式?如果這個函數的調用者已經完成了,golang阻塞函數會發生什麼?

package main 

import (
    "context" 
    "fmt" 
    "time" 
) 

func interruptable_call() <-chan time.Time { 
    return time.After(1 * time.Second) 
} 

func A(ctx context.Context) int { 
    for { 
     select { 
     case <-ctx.Done(): 
      fmt.Println("func done") 
      return 1 
     case <-interruptable_call(): 
      fmt.Println("blocking") 
     } 
    } 
    return 0 
} 

func main() { 
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 
    defer cancel() 
    fmt.Println("go A") 
    go A(ctx) 
    fmt.Println("go A done") 
    select { 
    case <-ctx.Done(): 
     fmt.Println("main done") 
     break 
    } 
} 

回答

1

我不知道你所說的「同步問題」的意思,因爲這裏沒有同步。您需要使用的通道,waitgroups或其他任何方式,如果你想確保同步您的夠程產卵的宮殿組織完成了他們的任務。

在goroutine中發生的事情並不重要 - 如果它與主要的gouroutine不同步,它將在主要退出後不再存在。

無論如何,函數中異步調用函數的返回值將不會提供給您。

您可以檢查出的阻塞調用如何爲自己工作:

package main 

import (
    "context" 
    "fmt" 
    "time" 
) 

func interruptable_call(sleep time.Duration) <-chan time.Time { 
    fmt.Println("sleeping for ", sleep*time.Second) 
    time.Sleep(sleep * time.Second) 
    return time.After(0 * time.Second) 
} 

func A(ctx context.Context) int { 
    for { 
     select { 
     case <-ctx.Done(): 
      fmt.Println("func done") 
      return 1 
     case <-interruptable_call(2): 
      fmt.Println("blocking") 
     case <-interruptable_call(3): 
      fmt.Println("blocking") 
     case <-interruptable_call(4): 
      fmt.Println("blocking") 
     case <-interruptable_call(5): 
      fmt.Println("blocking") 
     } 
    } 
    return 0 
} 

func main() { 
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) 
    defer cancel() 
    fmt.Println("go A") 
    go A(ctx) 
    fmt.Println("go A done") 
    select { 
    case <-ctx.Done(): 
     fmt.Println("main done") 
     break 
    } 
} 
+0

將如何選擇執行時一個案例回報,而另一種情況仍在運行。這種情況下的函數調用會被終止嗎?以什麼方式? –

+0

按順序選擇運行案例以使「準備就緒」通道等待消息,但是如果已返回的通道獲取消息,則選擇語句選擇此案例並運行它。我不確定這是如何在內部工作的,但我的猜測是任何已經運行的案例都已經完成,並且由於select語句已經完成,所以沒有運行任何案例。 – Nebril

相關問題