title: Cancelling of execution of child processes using context
body: <p>I'm trying to figure out how to work with context pattern in Go.
  I'm simulating the case when multiple long running child goroutines need to be cancelled because of timeout of their execution. As I understood one of the main usages of context is to stop all child processes in case of I/O timeout or if user left page before end of processing.</p>
  
  <p>My code:</p>
  
  <pre><code>package main
  
  import (
      "context"
      "fmt"
      "time"
  )
  
  func doIt(ctx context.Context, filename string) {
      // simulate not ending file processing - 
      // internals of this loop could not change 
      // e.g. it is call of some third party or stdlib function that hangs
      for {
          fmt.Printf("processing file %s\n", filename)
          time.Sleep(50 * time.Millisecond)
      }
  }
  
  func main() {
      startFileProcessing()
      fmt.Println("End of processing")
      time.Sleep(500 * time.Millisecond)
      fmt.Println("Do something else")
  
  }
  
  func startFileProcessing() {
      // set file processing timeout
      ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100)
      defer cancel()
  
      // start two parallel processes
      go doIt(ctx, "file1")
      go doIt(ctx, "file2")
  
      select {
      case &lt;-ctx.Done():
          fmt.Println("file processing timeout")
          return
      }
  }
  </code></pre>
  
  <p><a href="https://play.golang.org/p/AbTlcMKYGh" rel="nofollow">Playground</a>.</p>
  
  <p>Which outputs:</p>
  
  <pre><code>processing file file2
  processing file file1
  processing file file1
  processing file file2
  processing file file1
  file processing timeout
  End of processing
  processing file file2
  processing file file2
  processing file file1
  processing file file1
  processing file file2
  Do something else
  </code></pre>
  
  <p>I expect not to see "processing file" lines after "file processing timeout".</p>
  
  <p>How to fix it? </p>
  
  <p><strong>Edit:</strong> @Mellow Marmot pointed out that context does not stop child goroutines on its own and proposed solution for this. But his changes are within loop in doIt function what doesn't answer the question completely because instead of for loop in doIt function there could be some third party (or stdlib) function call that couldn't be changed. </p>
  
  <p>So let me rephrase question - </p>
  
  <blockquote>
    <p>How to cancel some long running processes to internals of which I
    don't have access - that hangs for more time than timeout?</p>
  </blockquote>