код1
t2 = [ код2 ] fork. "Или forkAt:"
t3 = [ код3 ] fork.
код4.
На зелёных нитях это всё на одном процессорном ядре, т.е. код2 (нить t2), код3 (нить t3) и код4 (ещё какая-то нить) одновременно не выполняются, хотя трудно сказать, какой именно код выполняется. Семафоры используются, чтобы переключаться. К примеру, код2 поработал и встал (ждёт семафора2), запустилась какая-то другая нить, выбранная по каким-то правилам (приоритету и т.п.). Эта другая нить может послать семафору2 сигнал и код2 продолжится (всё остальное не работает).
Ещё мы можем вызвать из код2 что-то внешнее, к примеру, функцию из DLL. Пока мы не получим ответа, ни код2, ни код3, ни код4, код в имидже выполняться не будет (но может выполняться что-то вспомогательное типа сборки мусора - в другой OS-нити). Если это не специальный случай (вроде как у Squeak'а/Pharo TCP/IP асинхронный) и если это если не Threaded FFI.
Когда мы в нити t2 вызвали функцию f2 из dll, используя Threaded FFI, а потом вызвали в той же нити t2 ещё какую-то функцию, оба вызова должны ("незаметно" для программиста на ST) произойти в одной и той же OS-нити, хотя не в основной OS-нити VM. (По крайней мере, базоданновые драйвера это требуют для корректной работы). Нить t2 "подвисает" до получения ответа, но основная OS-нить продолжает работать.
"Полицефалия" добавляет запуск/останов имиджей-рабов из имиджа-хозяина и какой-то механизм передачи сообщений.
По идее, можно даже не заботиться об этом, просто запустить кучу имиджей, а данными обмениваться - даже XML-ками и JSON'ами (это для примера). Или даже можно запустить M одинаковых вебсерверов, назначить им разные порты, а перед ними поставить балансировщик нагрузки.