|INTRO & CONTENT:|
As RISC OS is a strong focus of this site, and it is a Cooperative Multitasking system, it seems a good idea to look at the positive and negitive sides of both Cooperative Multitasking and Preemptive Multitasking.
It is common place to see people put down Cooperative Multitasking, even though in reality the multitasking model is just as good as preemptive multitasking. Some of the positives are different, some of the negitives are different, in the end it balances out well.
To note, there are some advantages of single tasking as well. This is not covered here, as it is not the point of the document.
|Cooperative Multitasking Pros and Cons:|
Cooperative multitasking works by swapping out the task at a well defined system call point. In the case of RISC OS, as well as most other Cooperative Multitasking systems, this is done when an application checks for events (something that many Preemptive MT systems still require to be done). This works well, as for an application to remain responsive it must check for events regularly.
On Purely Cooperative Multitasking systems applications can fail to task out often enough, or even not task out at all and take over. This is the one thing that may be sometimes problematic, though it will not happen with software that is well written and frequently checks for events. Almost all cooperative Multitasking Systems provide some means of the user inturrupting the system and killing a task that has taken over the system.
Cooperitive tasks that do follow the rules are often very responsive, and easy to deal with. Also do to the the reduced amount of work needed when switching out tasks, the overhead of task switching is usually less than it is for a Preemptive Multitasking System.
Cooperative Multitasking also has the advantage of the applications deciding the best scheduling for them selves, easing the issue of potential wrong priority, or wrong scheduling algorithm.
|Preemptive Multitasking Pros and Cons:|
The look at preemptive multitasking is a whole can of worms. Preemptive multasking uses some form of timer inturupt to call a scheduling algorithm, that must determine if a task needs swapped everytime it is called, even if there is no task switching needed. Just the additional frequency of calling the scheduling algorithm increases the amount of time taken away from the running Tasks, and thus creates some amount of slow down (ideally little enough to be non-issue, though in practice usually noticible).
While a task can not take over, as the system will switch tasks no matter what, a task can become unresponsive if it fails to check for events frequently enough in most Preemptive Multitasking systems (including Unix, Linux, BeOS, Win32 systems, OS/2, X11, and Wayland). When this happens the task becomes a zombie task, and may cause other issues do to its unresponsive nature. A zombie task is often a big issue, and creates problems, often requiring a complete reboot of the computer in order to completely clean it up, even if it is forceably removed from the task queue and as much as possible of its memory and other resources are reclaimed.
It is very important for an application in common Preemptive Multitasking environments to remain responsive, and thus it is very important for them to frequently check for events. This should go without saying, though some seem to overlook it.
While there do exist systems that reduce the issues with remaining responsive (most notably AmigaOS), especially with WIMP based programs, even these systems can have a zombie task with poorly written code. Just because they use signals to deliver the events, and the applications singnal handler code likely does the most immediate reaction to the signal, does not make the body of the program check for the changes made by its signal handlers.
Figuring out the appropriate scheduling algorithm can be very difficult, and often one that fits well for one system will be near useless in a different system. There is a lot of research done in the area of task scheduling algorithms, as there is a lot to consider. For example how do you provide a completely fair algorithm, that makes sure that everyone gets a chance to run regardless of priority or how active higher priority tasks are?
There is also the issue of how to set your task priority, which is a more complex question that most programmers give it credit to be (and thus why much software seems to run way slower than it should, or takes more CPU time than it should). While it is true that a programmer should not get to wrapped up in this question when creating an applications or other tasked software, it is still important to give enough consideration to make an appropriate request of priority, and correctly set the status to awaken when sleeping between active states.
|Comparing Preemptive and Cooperative Multitasking:|
In both systems it is important for programs to check for events in the body of the program, and respond appropriately. The difference being the result of not doing so, with a Preemptive Multitasking system you end up with a "Zombie Task", in a Cooperative Multitasking System it can prevent other tasks from running and become unresponsive. In general both types of systems have means to terminate an unresponsive task, removing it from all task queues and reclaiming as much of its allocated resources as possible.
In Cooperative Multitasking Systems scheduling is timed by when the tasks running make calls to check for events, this is fairly effecient. The task is making a system call it has to make anyway, and is swapped out durring this time. From the perspective af a task that is swapped out (if there are other tasks that need to recieve events at the time), it appears as if it made the call and immediately recived a reply. This can be very effecient.
In Preemptive Multitasking Systems task scheduling is done by a scheduler that is called by some kind of timer inturrupt, and then determines what tasks need to be executed, starting with the highest priority, and thus determines if a task switch needs to happen before returning from the timer inturrupt. In addition to this, tasks still need to check for events in some way, usually by making some kind of system call.
Even "Deamon" / "Faceless Background Tasks" / "System Services" need to check for some forms of events to effectively do there job and provide services beyond just replies to calls (which does not need a Deamon at all). The different names are a result of different views of different system sources. As such the same potential and continous issues exist for "Deamon" as for all other tasks. In a preemptive Multitasking environment this can be desasterous, as a Zombie Task Deamon is likely to take a significant amount of processor time (do to never leaving the active queue) and not give the user any indication of the cause of the issue. In cooperative Multitasking Systems at least the user will note that the system seems to have become unresponsive and be able to inturrupt the task and find out what task needs to be killed.
One area of interest is that with a cooperative multitasking system it is more likely that porly written and less responsive applications of all kinds are less likely to be used, and this promotes programmers to write better code. In Preemptive Multitasking Systems some users will just do something else while waiting on a task to become responsive again (if it has not completely Zombied out), thus allowing for worse habits of programmers in checking for events. Also the fact that Preemptive Multitasking does not easily give away which Deamon task may have become a Zombie, thus taking up a lot of processor time, it can cause extended issues.
So it is that in many ways both are equal. For me personally, knowning the differences between them, I would much prefer to deal with the problems of using a Cooperative Multitasking system than to deal with the problems of a Preemptive Multitasking System. I also prefer the advantages of Cooperative Multitasking over those of Preemptive Multitasking. Both systems have there pros and cons, and each user should use which ever suits there usage best.
Memory protection has nothing to do with the Multitasking Model. There are many out there that incorrectly think that Cooperative Multitasking means a lack of protected memory, and also many that think that Preemptive Multitasking means Protected Memory. This is completely untrue, there are Preemptive Multitasking systems that completely lack Memory Protection (eg AmigaOS), as well as Cooperative Multitasking systems that do have Memory Protection (eg RISC OS or M$-Win16 in PMODE). To be complete there are a few single tasking systems that implement Memory protection. Thusly we omit any mention of Memory Protection in this descussion.