On Thu, May 29, 2003 at 10:47:35AM -0700, Dave Whipp wrote: > OK, we've beaten the producer/consumer thread/coro model to death. Here's a > different use of threads: how simple can we make this in P6: > > sub slow_func > { > my $percent_done = 0; > my $tid = thread { slow_func_imp( \$percent_done ) }; > thread { status_monitor($percent_done) and sleep 60 until > $tid.done }; > return wait $tid; > }
At first glance, this doesn't need a thread - a coroutine is sufficient. Resume the status update coroutine whenever there has been some progress. It doesn't wait and poll a status variable, it just let the slow function work at its own speed without interruption until there is a reason to change the display. In fact, it probably doesn't need to be a coroutine either. A subroutine - display_status( $percent ) - should't require any code state to maintain, just a bit if data so all it needs is a closure or an object. At second glance, there is a reason for a higher powered solution. If updating the display to a new status takes a significant amount of time, especially I/O time, it would both block the slow function unnecessarily and would update for every percent point change. Using a separate process or thread allows the function to proceed without blocking, and allows the next update to jmp ahead to the current actual level, skipping all of the levels that occurred while the previous display was happening. Instead of sleep, though, I'd use a pipeline and read it with a non-blocking read until there is no data. Then, if the status has changed since the last update, do a display update and repeat the non-blocking read. If the status has not changed, do a blocking read to wait for the next status change.