Возможна такая ситуация - кооперативная многозадачность (оно же -
простой цикл, while(1){} с ручным вызовом по-очереди своих
процедур, они же "подзадачи", они же микротреды). Оно же известно
под названием "идиомы" игрового mainloop'а: //mainloop
while(1)
{
Task_ReadSensors(); // Хотя это простой вызов функции, ничто не мешает рассматривать её как периодический вызов шедулером "потока"
Task_MainLogic(); // И это тоже другой поток.
Task_SetDisplay(); // (Потоки исполняются по-очереди как и будет на одном процессоре)
Task_NetworkIO();
}
В этом случае столкнувшись с заблокированным Mutex/Lock'ом необходимо что-то делать. В вытесняющей многозадачности поток можно засыпить и шедулер переключится на него только если Mutex/Lock реально освободится (иначе, дескать, нет смысла, ресурс занят, ждём...). А здесь в столь простом случае можно или вручную проверять лок и выполнять return из функции подзадачи, (экономя время и переходя к следующей), либо же написать какое-то более элегантное решение, типа WaitForLock() а внутри выход через setjmp/longjmp... Суть в том чтобы покинуть функцию подзадачи, перейдя к следующей...