3

At several points of my program, I use launch to start a coroutine that does some background tasks. Then, at some point, I return from the main function. A simplified version of my program could look like this:

fun main(args : Array<String>)
{
    launch {
        delay(10000) // some long running operation
        println("finished")
    }
}

Now, the coroutine starts as expected and starts running the operation - and then the program exits. If I don't return from main or replace launch with thread, everything works as expected. So how can I, given that I don't keep track of all coroutines started in my program (hence I cannot use .join() or .await()), make sure that all coroutines finish before my program exits?

msrd0
  • 7,816
  • 9
  • 47
  • 82

1 Answers1

3

So how can I, given that I don't keep track of all coroutines started in my program (hence I cannot use .join() or .await()), make sure that all coroutines finish before my program exits?

You need to keep track and await the results at some point in order to be sure that those coroutines have finished. That’s because “coroutines are like daemon threads”:

Active coroutines do not keep the process alive. They are like daemon threads.

This is not the case for regular Java Threads which are non-daemon by default.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
  • No, when I exit from the main methods java threads keep running in the background – msrd0 Jan 06 '18 at 09:51
  • Sorry I was on the wrong path you’re right, these threads are non-daemon – s1m0nw1 Jan 06 '18 at 09:59
  • so basically if I could tell the coroutines to run on such a thread they should not be terminated - but my understanding is that `launch`, unless otherwise specified, uses a `ForkJoinThreadPool` behind the scenes? – msrd0 Jan 06 '18 at 10:01
  • But I don’t think this is possible according to https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#coroutines-are-like-daemon-threads – s1m0nw1 Jan 06 '18 at 10:04
  • nope, `launch` wants to have a `CoroutineContext`, not a thread pool. so is there any way I can tell the coroutine context to run on non-daemon threads? – msrd0 Jan 06 '18 at 10:04
  • You are confusing analogy with fact. Coroutines are neither threads nor daemon threads. The only point was that they behave _like_ daemon threads in the sense that a still active coroutine won't keep the JVM process alive. It makes no difference what thread you run the coroutine on, and the coroutine isn't even bound to any specific thread. – Marko Topolnik Jan 06 '18 at 11:04
  • @MarkoTopolnik As of my understanding the coroutine is bound to a thread pool. So if those threads are non-daemon threads, they should stay alive after I exit `main`, right? And keep executing my coroutines until they all finish and no threads of that thread pool are active anymore – msrd0 Jan 06 '18 at 20:51
  • 1
    It's an indirect connection, over the optional facility of the coroutine context. But yes, if you start an explicit executor service and use it as the context for your coroutines, your application will live on until you explicitly shut down that executor or until the executor itself decides to stop the threads. A `cachedThreadPool` will automatically stop a thread after 60 idle seconds. – Marko Topolnik Jan 07 '18 at 02:25
  • 2
    So, even if you set it up like that, your application won't wait for the coroutines, but for the executor service's threads, to complete. Depending on circumstances, they may never complete or even complete earlier than your coroutines (e.g., if a coroutine is suspended without being scheduled to resume). – Marko Topolnik Jan 07 '18 at 08:18