Skip to content

Proposals concerning thread pool termination problemsΒ #1242

@patengel

Description

@patengel

I use rayon inside an application delivered as windows DLL. I face the problem similar to #688 or #959, that I have to clean up rayon threads before unloading the DLL.

Since the global thread pool can not be terminated, I use the following pattern:

let pool = rayon::ThreadPoolBuilder::new().build().unwrap();
pool.install(something);
drop(pool);

std::thread::sleep(std::time::Duration::from_secs(1));

But even this has two draw backs:
First: I need the sleep to ensure improve the probability that all threads are really shut down, when afterwards the DLL is unloaded. Since the drop only sends the threads a signal to finish.

I would propose to have a new method on ThreadPool which also waits for all threads to finish. Some naive implementation could be

pub fn terminate_and_wait(self) {
    let registry = self.registry.clone();
    drop(self); // sends all threads the quit signal
    wait_for_arc(registry);
}

fn wait_for_arc<T>(x: Arc<T>) -> T {
    match Arc::try_unwrap(x) {
        Ok(inner) => inner,
        Err(x) => {
            std::thread::sleep(std::time::Duration::from_millis(1));
            wait_for_arc(x)
        }
    }
}

Second: In my tests I can not assert that I never use the global thread pool by mistake.

I would propose to have a feature flag called something like no_global_thread_pool, which replaces the code were currently implicitly the global thread pool is built with a panic.

I started this issue, since I did not find any activity on the two linked issues and wanted to start the discussion again with some proposals how the problems could be tackled.

If the above proposals are fine, I could also try to implement them myself...

Alternatively to the second proposal, it would also help to have a feature flag cleanup_global_thread_pool, which does something like the following:

#[cfg(feature = "cleanup_global_thread_pool")]
#[ctor::dtor]
fn cleanup() {
    global_thread_pool.terminate_and_wait();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions