La multitasca cooperativa (en anglès, cooperative multitasking), també coneguda com a multitasca no apropiativa (non-preemptive multitasking), és una tècnica de multitasca en la qual el sistema operatiu o l'entorn d'execució no interromp mai un procés en curs per donar pas a un altre. En aquest model, els processos cedeixen el control voluntàriament de manera periòdica, quan estan inactius o quan queden lògicament bloquejats. Aquesta tècnica rep el nom de cooperativa precisament perquè depèn que tots els programes cooperin perquè l'esquema de planificació funcioni.
Funcionament En el model cooperatiu, cada tasca s'executa fins que decideix explícitament que ha de pausar la seva activitat, normalment perquè ha de fer una operació d'entrada/sortida o perquè ha completat una part del seu treball. En aquell moment, cedeix el control al planificador, que pot escollir una altra tasca per executar. Aquesta cessió voluntària es coneix com a yield.
A diferència de la multitasca apropiativa, on el sistema operatiu interromp les tasques sense el seu consentiment mitjançant interrupcions de temporitzador, en la multitasca cooperativa són els mateixos processos els que han de decidir quan és el moment adequat per cedir el control.
Avantatges i inconvenients La multitasca cooperativa presenta diversos avantatges respecte al model apropiatiu. En primer lloc, requereix menys recursos del sistema, ja que no necessita el cost dels canvis de context forçats. En segon lloc, ofereix més granularitat, perquè el programador coneix els punts exactes on les seves tasques poden ser pausades, fet que simplifica el raonament sobre seccions crítiques i redueix la necessitat de primitives de sincronització complexes com mutexs o semàfors.
El principal inconvenient és que el sistema depèn completament del bon comportament de cada tasca. Un sol programa mal dissenyat o amb un bucle infinit pot monopolitzar el processador i bloquejar tota l'aplicació o el sistema operatiu. Aquesta fragilitat va ser un dels motius pels quals la majoria de sistemes operatius generals van abandonar aquest model en favor de l'apropiatiu.
Context històric El concepte de corutina, base teòrica de la multitasca cooperativa, va ser formalitzat per Donald Knuth el 1968 a The Art of Computer Programming. Com a model de planificació, la multitasca cooperativa va ser el principal utilitzat per les aplicacions de 16 bits de Microsoft Windows anteriors a Windows 95 i Windows NT, així com pel Mac OS clàssic. El sistema operatiu NetWare també va utilitzar multitasca cooperativa fins a la versió 6.5, i Symbian OS la va emprar als dispositius mòbils dels anys 2000.
Un cas particularment rellevant és el llenguatge Erlang, desenvolupat per Ericsson el 1986, que implementa un sistema de processos lleugers cooperatius capaç de gestionar milions de tasques concurrents. Aquesta arquitectura va influir decisivament en el disseny posterior de plataformes asíncrones com Elixir i en el resorgiment del model cooperatiu en l'era de les aplicacions de xarxa massivament concurrents.
Aplicacions modernes Tot i que els sistemes operatius moderns de propòsit general utilitzen multitasca apropiativa, el model cooperatiu ha tornat a guanyar rellevància en l'àmbit de la programació asíncrona dins d'un sol fil d'execució. Aquest renaixement està directament lligat al problema C10k, formulat per Dan Kegel el 1999, que va posar de manifest la incapacitat dels models tradicionals basats en fils per gestionar deu mil connexions concurrents en un sol servidor de manera eficient.
Llenguatges com Python (amb la biblioteca asyncio), JavaScript (amb el seu bucle d'esdeveniments) o Kotlin (amb les coroutines) implementen formes de multitasca cooperativa per gestionar de manera eficient grans quantitats d'operacions d'entrada/sortida concurrents. En aquests entorns, les tasques es defineixen mitjançant funcions especials anomenades corutines, que poden pausar la seva execució i ser represes posteriorment. Quan una corutina arriba a un punt de pausa, cedeix el control al bucle d'esdeveniments, que fa avançar altres corutines amb feina pendent.
Sintaxi async/await Per identificar de manera explícita els punts de pausa, els llenguatges moderns han adoptat les paraules clau async i await, introduïdes per primera vegada en C# el 2012 i adoptades posteriorment per Python (a partir de la versió 3.5), JavaScript (ECMAScript 2017), Rust i Kotlin, entre d'altres. A Python, aquesta sintaxi va ser formalitzada per la PEP 492 el 2015. Una funció marcada amb async es converteix en una corutina, i l'expressió await davant d'una operació potencialment llarga (com una petició de xarxa o una consulta a una base de dades) indica al planificador que pot cedir el control mentre s'espera el resultat.
Limitacions Tot i la seva eficiència en escenaris dominats per operacions d'entrada/sortida, la multitasca cooperativa presenta limitacions importants en càrregues intensives en CPU. Una operació de càlcul prolongat pot bloquejar tot el bucle d'esdeveniments i impedir l'execució de la resta de tasques, fins i tot d'aquelles que tindrien feina urgent.
Per aquest motiu, els entorns que implementen multitasca cooperativa solen combinar-la amb altres models de concurrència. La biblioteca asyncio de Python, per exemple, ofereix mecanismes per delegar les operacions intensives en CPU a un conjunt de processos o fils paral·lels mitjançant l'API run_in_executor, preservant així la responsivitat del bucle principal. Aquest enfocament híbrid és habitual en aplicacions reals: el model cooperatiu gestiona la concurrència d'entrada/sortida, mentre que el multiprocés o el multifil absorbeix la càrrega computacional.
Una altra limitació estructural és que la multitasca cooperativa, per definició, no aprofita múltiples nuclis de CPU dins d'un mateix bucle d'esdeveniments. L'escalabilitat horitzontal en sistemes multinucli requereix llançar diversos bucles d'esdeveniments en processos separats, una estratègia coneguda com a worker pool (conjunt de processos treballadors) i utilitzada per servidors web asíncrons com Gunicorn (Green Unicorn, un servidor WSGI per a Python) o Uvicorn (un servidor ASGI basat en uvloop).
Vegeu també Multitasca apropiativa Multitasca Programació asíncrona Corutina Bucle d'esdeveniments
Referències
Categoria:Sistemes operatius Categoria:Programació