Which mutex should I use for single-thread Tokio tasks?

The problem is:

I have task A and task B, and both of them requires resource M (which I need a mutex to guard). In a single-thread Tokio context, task A is firstly executed, and it acquires M. In the middle of A's execution, it awaits, so scheduler starts to execute task B. B requires M, but A has acquired M so I want B to await (not block current thread).

As pointed out in tokio tutorial:

A synchronous mutex will block the current thread when waiting to acquire the lock. This, in turn, will block other tasks from processing. However, switching to tokio::sync::Mutex usually does not help as the asynchronous mutex uses a synchronous mutex internally.

So both std::sync::Mutex and Tokio::sync::Mutex don't work for this situation, and I wonder which mutex (or other synchronous mechanisms) should I use for this situation?

Tokio Mutex still blocks other tasks trying to access shared state from processing, but at least it doesn't block the whole thread.


From the play-ground, the tokio::sync::Mutex does help even though it uses a synchronous mutex internally.

If you hold the lock across await points you want tokio::sync::Mutex.

I think the tutorial needs clearer language there since I'm not sure what it's trying to warn against. Mutex block task from processing (that's kind of the point of them). I don't see why the tokio mutex using synchronous primitives internally matters. It seems to just uses those to build a semaphore with a wait queue that can talk to the scheduler, nothing that blocks long by Tokio's standards. Maybe that was written before the intrusive lists optimization in the wait queue, and things could block long enough to be problem back then.

Although it uses a synchronous mutex internally, it is not used in the same way as if you had used the synchronous mutex directly. This particular snippet is mostly an argument that shows that the Tokio mutex is not going to be faster than the blocking one, in cases where both can be used.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.