Dealing with multiple threads

Hey there, so I have a small program with the following setup:
It has two threads, the main one where most of the action happens, and a "disposable" thread which I use to run a constant loop without hanging up the program.

Before needing the later thread, I was using Rc<RefCell<Struct>> to be able to use the methods of a struct I couldn't derive Clone to inside static closures (event handlers for FLTK widgets). However I later switched to Arc<Mutex<Struct>> since I needed that multithread capability.

So far I've been able to get an external "stop signal" working for the loop, save for the delay that occurs after the first time I close. The issue lies in the fact that once I call a method of the struct outside of the separate thread, the clone done via Arc::clone() stops responding.

Snippet of the code:

let var = Arc::new(Mutex::new(var));
    // Choice is a "HoldBrowser" from FLTK
    choice.set_callback({
        let loop_is_active = Arc::new(Mutex::new(false));
        move |browser| match choices_list[(browser.value() - 1) as usize] {
            "Threaded" => {
                *loop_is_active.lock().unwrap() = true;
                let should_loop = Arc::clone(&loop_is_active);
                let clone_var = Arc::clone(&var);
                thread::spawn(move || {
                    while *should_loop.lock().unwrap() {
                        thread::sleep(time::Duration::from_millis(200));
                        clone_var.lock().unwrap().do_something(2);
                    }
                });
            }
            "NotThreaded" => {
                *loop_is_active.lock().unwrap() = false;
                //The moment this case is reached and the instruction bellow is executed, clone_var inside "Threaded" stops working. Any other use outside of the separate thread works fine.
                var.lock().unwrap().do_something_else(0);
            }
            _ => {}
        }
    });

Code abominations aside, can someone help me figure out why this is happening?

Are you just referring to the fact that while do_something_else is running, the other thread isn't able to execute do_something? (That would be because you locked the mutex for the duration of that call.) If it's something else, you'll need to tell us more details; it's very hard to tell what exactly the behavior is that you're observing and what you'd be expecting to happen instead / what you're aiming to achieve.

Ah no, rather after running do_something_else, do_something does not work anymore afterwards on any call to it inside the separate thread. As for expecting, well, its just it not suddenly not working.

Apologies if I seem lost with the responses (kinda am), first timer on asking in forums.
:sweat_smile:

Hmm, you're setting the loop_is_active value to false which is going to stop the loop from running. Is that just what's happening? Or are you expecting the loop not to stop for some reason?

Wait, nevermind, each call crates its own independent loop_is_active value, right? No it doesn't, my point above still stands.

Not that, the calling order is

  • Threaded
  • NotThreaded
  • Threaded

The loop stops the first time as expected, on the second "Threaded" the loop starts again, but do_something() inside the loop does not work anymore, the rest of the code does (Including stopping the loop again).

I can call do_something() as I please as long as all calls are done inside the (muliple) separate threads, the moment "NotThreaded" is called all methods for clone_var stop working when used inside the loop thread.

Ah, now the question makes a lot more sense to me.

Can you describe more precisely what exactly "stop working" means? Like... if you have a print statement inside of the definition of do_something doesn't it work? But putting a print statement inside of the loop of the looping thread directly does still get executed (repeatedly)?

Edit: I'll have to leave for today, I hope someone else can help you in the meantime if your problem persists ^^

Ok so I do not know what I did, but I got it working, I- uh-...

brain.exe stopped working Ah, the wonders of coding.

Anyways, guess that solves that? Thanks for the help :joy:.

1 Like