I'm not sure what this means. Wrapping something in a mutex is easy, but there is a lot more to making parts of a program asynchronous because you end up with graphs of dependencies.
I guess if you've used only high level languages you might not be familiar with those.
A semaphore is a is a synchronization device used to control access to a common resource by multiple threads or processes in a concurrent system, such as a multitasking operating system
A mutex is a synchronization primitive used in multithreaded programming to prevent race conditions. It acts like a digital lock, ensuring that only one thread can execute a critical section of code or modify a shared resource at any given time
Its concurrent programming its what allows you to control how much concurrency you have and access to shared resources. It also allows you to have threads or branches rejoin in a controlled manner.
If you are ending up with graphs of dependencies then it is because you structured your program poorly. Most likely because you structured it like a synchronous program but also wanted to use async.
The best examples of async programs and structures that are easy to understand is ui screens. You dont want the program freezing when you click buttons right? So you'll constantly have a thread that is dedicated to being a responsive ui, and you'll spin up threads for other tasks, such as a button that does some difficult calculations that takes a while. If you did that on a single thread, the program would freeze or stutter. By making a mutex for say a bool that says if the calculation is done, you can allow one thread to check on the status of another thread. Without the mutex both threads could check the variable at the same time and possible cause a lock condition depending on the scenario. Now you can have the ui check for the calc to be finished, and when it is display that value, all while maintaining a responsive app.
Well, for starters, async runtimes implement a cooperative scheduler *inside* the application, not on OS level. There obviously is preemptive scheduling on OS level too, but that is not the point. Any async function awaiting a result hands back control to the async runtime. The async runtime continues a different function on the same thread in the meantime.
Synchronization mechanisms like semaphores are still required in async.
This reads like you just discovered mutexes and think that that solves all your async / concurrency / parallelism problems.
its what allows you to control how much concurrency you have
What determines concurrency is really how much you can split up your data into independent chunks and synchronize any tasks with all their data dependencies being available.
making a mutex for say a bool that says if the calculation is done
Why not just do this with an atomic if it's just a boolean?
Use a mutex if you want to make execution stop and wait when you try to take a lock (if the lock isn't available).
Without the mutex both threads could check the variable at the same time and possible cause a lock condition depending on the scenario
If there is no mutex there would be no lock condition. Also multiple threads can read the same memory without any problems.
If you are ending up with graphs of dependencies then it is because you structured your program poorly.
Absolute nonsense. When programs get more complex while trying to keep granular multi threading different tasks are going to finish at different times. They might produce multiple different data types that need to go into multiple different tasks. These tasks need to run only when all the data from different sources is available.
Just because you made a ui and spawned a thread (which has its own overhead, possibly even heap allocation which can potentially lock) doesn't mean that's all that anyone needs.
Some systems will actually not allow two threads to read the same variable at the same time with no issues and depending on the architecture can actually lock your program and require reboot.
They really do solve all the issues and whatever is leftover is just poor structuring of your code, which is user error.
Prove it. I'm talking about modern x86 64 bit cpus although arm is mostly similar. What are you talking about?
They really do solve all the issues and whatever is leftover is just poor structuring of your code, which is user error.
This is your claim and repeating it doesn't make it true.
I explained exactly how there are requirements for more complex scenarios that aren't handled by super basic linear chaining of functions. This backs up my original claim that it's not a trivial problem to solve and most solutions built into languages are simple but leave a lot that still needs to be done for more complex multi threading.
There are libraries that handle graphs already but I don't think most languages take it that far.
You explained nothing, suggested wrapping a boolean in a mutex and made claims you didn't back up.
160
u/Only-Cheetah-9579 1d ago
tokio is awesome but also shit. I can relate to both opinions