Make a pool of threads: when drop the sender channel?

Hello community,

I’m trying to make a pool of thread workers:

use crossbeam::channel::unbounded;
use crossbeam::thread;

fn main() {
    let (sender, receiver) = unbounded();
    let workers_count = 2;
    let job_count = 4;
    let mut current_cpu_i = 0;

    thread::scope(|scope| {
        for i in 0..job_count {
            // Enter here when count of spawned thread is equal to worker
            // capacity or when no more job to do
            if current_cpu_i == workers_count || i == job_count - 1 {
                for received in &receiver {
                    println!("Got: {}", received);
                }
                current_cpu_i = 0;
            // Enter here to spawn thread worker
            } else {
                let thread_sender = sender.clone();
                current_cpu_i += 1;
                scope.spawn(move |_| {
                    thread_sender.send(i).unwrap();
                });
            }
        }

    })
    .unwrap();

    println!("ok")
}

Execute this code result infinite wait into for received in &receiver {:

Got: 0
Got: 1

In this discussion it appears than we must drop the sender object. But if i try to drop it before for received in &receiver {, it can’t work because sender will be used more later:

error[E0382]: use of moved value: `sender`
  --> src/main.rs:15:22
   |
15 |                 drop(sender);
   |                      ^^^^^^ value moved here, in previous iteration of loop
   |
   = note: move occurs because `sender` has type `crossbeam_channel::channel::Sender<i32>`, which does not implement the `Copy` trait

How to deal with this problematic ? Or maybe, there is a easier way to use a worker pool with crossbeam ?

Hi, what do you think of this?
The issue is that you are trying to receive while keeping the sender around to reuse it on the next iteration, I don’t think that’s possible.
Also, I don’t think this is making a thread pool, you just make new threads every iteration, like said in this issue you might want to take a look at rayon.

Hello @leudz,

Thank’s for your help. Your code proposal is fine thank’s. I took a look about rayon, but i didn’t understand how to use it in my case :confused:

bux.

The simple switch looks like this, but with rayon you have access to parallel iterators so why not use them? And this way you possibly “cut” your work in 4.

Thank’s for these example @leudz ! I learning with them !