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

Seperating Thread creation from job execution. #7

Closed
Kimundi opened this issue Apr 20, 2015 · 6 comments
Closed

Seperating Thread creation from job execution. #7

Kimundi opened this issue Apr 20, 2015 · 6 comments

Comments

@Kimundi
Copy link

Kimundi commented Apr 20, 2015

Right now, the ScopedPool API works in such a way that the handle that represents the spawned threads and the lifetime-bound RAII guard for the actual execution of jobs are one and the same type.

This means its not possible to re-use the same pool of threads across different batches of job closing over disjoints lifetimes, eg:

let pool = ScopedPool::new(4);

for _ in 0..10 {
    let mut a = [1, 2, 3];
    for e in &mut a {
        pool.execute(move || *e += 1);
    }
    // <join the existing threads here without ending them>
}
src/pool_cache.rs:19:27: 19:28 error: `a` does not live long enough
src/pool_cache.rs:19             for e in &mut a {
                                               ^
src/pool_cache.rs:14:35: 28:6 note: reference must be valid for the block at 14:34...
src/pool_cache.rs:14     fn scoped(&mut self) -> Guard {
src/pool_cache.rs:15         let pool = ScopedPool::new(4);
src/pool_cache.rs:16 
src/pool_cache.rs:17         for _ in 0..10 {
src/pool_cache.rs:18             let mut a = [1, 2, 3];
src/pool_cache.rs:19             for e in &mut a {
                     ...
src/pool_cache.rs:18:35: 22:10 note: ...but borrowed value is only valid for the block suffix following statement 0 at 18:34
src/pool_cache.rs:18             let mut a = [1, 2, 3];
src/pool_cache.rs:19             for e in &mut a {
src/pool_cache.rs:20                 pool.execute(move || *e += 1);
src/pool_cache.rs:21             }
src/pool_cache.rs:22         }

I propose the introduction of a new type PoolCache whose sole purpose is to spawn N threads, and which has constructor methods for getting a RAII handle that allows temporary usage as a scoped pool:

let pool_cache = PoolCache::new(4); // Allocate 4 Threads and keep them ready

for _ in 0..10 {
    let mut a = [1, 2, 3];
    let pool = pool_cache.scoped(); // Create a scoped pool with a lifetime bound local to this scope
    for e in &mut a {
        pool.execute(move || *e += 1);
    }
    // pool drops here, which causes the threads to wait ("join") for completion and get returned to the cache.
}
@alexcrichton
Copy link
Contributor

cc @aturon

@aturon
Copy link

aturon commented Apr 21, 2015

Yes! I've been wanting to do this since I first introduced scoped :)

@blaenk
Copy link

blaenk commented Apr 23, 2015

Yesss, I thought I was doing it wrong for wanting this.

@yongqli
Copy link

yongqli commented Jul 28, 2015

👍 Yes, this is exactly what I want. My use case is: I want a global thread pool to avoid paying the cost of thread creations, while dispatching jobs to it within a function to speed things up.

@reem
Copy link

reem commented Mar 5, 2017

Fwiw https://github.com/reem/rust-scoped-pool basically provides this interface in the now safe manner. (and the Pool is freely clonable as well).

@Kimundi
Copy link
Author

Kimundi commented Mar 5, 2017

Yeah, I think this issue is out of date now. :)

@Kimundi Kimundi closed this as completed Mar 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants