Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: add WaitTimeout method to Cond #9578

Closed
mei-rune opened this issue Jan 13, 2015 · 9 comments
Closed

sync: add WaitTimeout method to Cond #9578

mei-rune opened this issue Jan 13, 2015 · 9 comments

Comments

@mei-rune
Copy link

can add func (c *Cond) WaitTimeout(timeout time.Duration) bool for sync.Cond,

example:
...
if !this.c.WaitTimeout(10 * time.Second) {
return errors.New("time out")
}
...

@adg adg changed the title can add func (c *Cond) WaitTimeout(timeout time.Duration) bool for sync.Cond sync: add WaitTimeout method to Cond Jan 13, 2015
@adg adg added the feature label Jan 13, 2015
@adg
Copy link
Contributor

adg commented Jan 13, 2015

Here's how you can do it:

done := make(chan struct{})
go func() {
  cond.Wait()
  close(done)
}()
select {
case <-time.After(timeout):
  // timed out
case <-done:
  // Wait returned
}

@bradfitz
Copy link
Contributor

That's how you do it at a lot of cost (goroutine + 2 channels). The OP might be asking for scheduler integration.

@runner-mei, why do you want this?

@minux
Copy link
Member

minux commented Jan 13, 2015

The problem of timed wait is that for normal use cases, you also
want kill the task to avoid leaking/wasting resources. but that's not
going to happen for goroutine, you will need to do your own framework
to have killable tasks, but in that case, you will definitely need to write
your own timed wait.

However, if the requirement is not waiting and killing the task if it
executes too long, I think using sync.Cond is the wrong solution.
You should use channel to signal readiness and then it's trivial
to use select and time.After for timeout.

It all depend on the use case.

@mei-rune
Copy link
Author

my case is:

next_id := 0

// goroutine (net read):
for {
   id := recv() // read from network
   mu.Lock()
   next_id = id
   mu.Unlock()
   cond.Broadcast()
}

// goroutine n:  0 <= n < 100 in any time
func wait(id int, t time.Duration) bool {
   mu.Lock()
   defer mu.Unlock()
   start_at := time.Now()
   for next_id < id {
      if  t >= 0 {
         return false
      }

      if !cond.WaitTimeout(t) {
        return false
      }
      t = time.Now().Sub(start_at)
   }
   return true
}

Create cost of channel is too high, because calling too often

@ianlancetaylor
Copy link
Contributor

Condition variables are generally not the right thing to use in Go, it's hard for me to see why we should add features to them.

@rsc
Copy link
Contributor

rsc commented Apr 10, 2015

I agree with Ian.

@rsc rsc closed this as completed Apr 10, 2015
@dtromb
Copy link

dtromb commented Apr 28, 2015

"Condition variables are generally not the right thing to use in Go, it's hard for me to see why we should add features to them."

@ianlancetaylor - Please provide a reasonable alternative or a "Go-like" way to do this, here, then?

You haven't neglected to add a feature, you've taken /away/ a feature from the more-or-less standard set of stuff any systems programmer expects to find where a Mutex/Cond pattern is provided. All thre threading libraries I know directly support this, and I cannot find any good alternatives. (Yes, I've read https://blog.golang.org/pipelines The question(s) are about accomplishing this standard pattern w/o the cost of creating lightweight tasks or additional object allocations - it often happens in extremely tight loops)

@ianlancetaylor
Copy link
Contributor

If you carefully design an abstract problem so that you must have condition variables and can not use channels, then, yes, there are cases where a timeout on a condition variable becomes useful. In Go, however, we prefer channels. Mutexes have their uses in Go. Condition variables are almost always better implemented using channels.

To say more requires discussing a specific problem.

@ianlancetaylor
Copy link
Contributor

Sorry, I should also have said: this is a discussion to have on the mailing list golang-nuts@googlegroups.com, not on a closed issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants