Smartphone Operating System (779883), страница 17
Текст из файла (страница 17)
Note that, in this model, a single threadcan block an application. If multiple threads need the kernel, only onegets through and the rest block.An alternative to a many-to-one model is a model where the kernelspawns a new thread for each user thread that makes a kernel-level request(see Figure 4.4b). This is called a one-to-one model of kernel threading.Each kernel thread services the requests from a single user thread. Thisincreases concurrency and eliminates the backlog of requests.
In the oneto-one model, each thread in an application could be serviced, whichmeans an application does not block when a single thread needs kernelservices. In this model, threads are created and destroyed based on therequests that come in. The overhead of creating kernel threads can startto affect the performance of applications. If an application requires manykernel services, it also bears the burden of creation and destruction ofkernel threads. For this reason, operating systems that support this model(e.g., Windows 2000) restrict the number of threads supported by thesystem.To get around constant kernel creation, most operating systems use amany-to-many model of kernel threading, shown in Figure 4.4c. In themany-to-many model, threads are created once and remain active.
Manythreads are created on system startup, but not the number needed fora one-to-one match with user threads that make kernel requests. Thesethreads are kept around in a thread pool to service many requests. Theresult is some backlogging of requests as with the many-to-one model,but more efficient and concurrent processing of those requests as withthe one-to-one model. The many-to-many model is better adapted formultiprocessor systems, as the number of kernel threads can be tunedfor the number of processors. Many Unix implementations support themany-to-many model.Issues with multithreadingThere are many issues that surface when we expand our concept ofprocesses and scheduling to include threads.• Thread management : threads must be managed and scheduled; theygo through states similar to processes (see Figure 4.1). Applicationscontrol the creation of threads but the actual creation and movement72PROCESSES AND THREADSthrough states is done by the kernel.
Note that this adds more complexity to the idea of scheduling a process and complicates decisionsabout scheduling. If a scheduler gives equal time to all processes, itmust choose one thread to run on behalf of a process or give a tinyamount of time to each thread in a process, so that the total time onthe threads equals the time spent on a process.• Process creation : should a thread be allowed to create a new processor just other threads within a process? If we consider an applicationthat does not create threads to be an application with a singlethread, then we cannot deny any thread the ability to create aprocess (since such an application has no real ‘main’ thread).
Ifany thread can create a process, then what does the new processlook like? As we see later in this chapter, processes typically createother processes by cloning themselves. Do we clone a process,including created threads? The answer to this is usually yes and no.Systems that support process forking (the act of cloning a process)typically give that support in two versions: with and without allthe created threads. This complicates programming with processcreation.• Thread cancellation : terminating a thread is referred to as threadcancellation. Because threads operate inside the larger context of aprocess, cancellation is not as traumatic to the system as processtermination. In asynchronous cancellation, a thread may immediately cancel another thread.
However, concurrency issues arise whenthreads are cancelled. For example, if a thread is updating data sharedby other threads in a process, what happens to the data when a threadis cancelled? Often data is corrupted when such an event occurs.This is usually remedied by using deferred cancellation. In this situation, a thread cancels itself when the system tells it to terminate butwaits for the appropriate time, for example, when no data is beingmanipulated.We referred to interrupts that operate between processes as signals.One process can signal another to indicate a particular condition. Whenan application has multiple threads, it raises the question about whichthread receives a signal when one arrives.
All threads could receive thesignal, or one or more threads could indicate they are waiting to receivea signal. Usually, all threads receive a signal sent to a process, althoughonly certain threads deal with it.AN OVERVIEW OF THE PROCESS MODEL73Active Objects in Symbian OSThreads in an operating system can be viewed as lightweight processes.As a lightweight process, a thread has many properties that a processdoes: it has an execution path, it can be scheduled, it uses resources, etc.Also, like a process, it requires bookkeeping: recording of where a threadis in its execution must occur so that the thread may be restarted when itgets a chance to execute on the CPU.
So, while a thread is lightweight, itstill has an effect on a running system.On a system with restricted resources, such as a smartphone, the weightof threads has an effect. Much care is taken in restricted environmentsto be as light as possible. In these environments, processes are kept to aminimum and even threads are scrutinized as to their necessity. There istypically one main thread that controls most aspects of an application.When there are multiple threads in an application, they are usuallyspawned from the main thread and meant to deal with situations thatcause waiting, for example, network communication or device I/O, so asto free up the main thread for other functionality.It is possible to make a process – a kind of lightweight thread – thathas less of an effect; it follows a fixed kind of behavior and is lighteron a restricted system. In Symbian OS, this lightweight thread is calledan active object. Active objects are specialized threads that have someunique characteristics.• Each active object is specifically focused on an event that causes athread or process to block: communication, device I/O, and so on.• Each active object works with a single active scheduler that listensfor events for which the object is waiting.
All active objects withina process use the same scheduler; different schedulers can be usedbetween processes.• An active object defines a specific entry point in its code that is usedby the active scheduler when an event is generated. The entry point isrepresented by a standard function call that is defined for each activeobject.• While waiting for an event, all active objects within a single process,because they are maintained by the same scheduler, act as a singlethread to the system.Active objects in a single process, therefore, can be coordinated by asingle scheduler implemented in a single thread.
By combining code into74PROCESSES AND THREADSone thread that would otherwise be implemented as multiple threads,by building fixed entry points into the code, and by using a singlescheduler to coordinate their execution, active objects form an efficientand lightweight version of standard threads. See Section 4.2 for somecoding examples using active objects.Contexts and Context-switchingA process has a context, that is, the collection of system resources thatit is using represented by the process’s PCB. These resources include theregister set the process is using, the program counter, memory contentsthat implement data in its code, open files, identifying information suchas a process identifier, and so on.When a process moves to or from the running state to execute ona processor, several things must happen to the context.
The context ofthe process that preceded the current process must be extracted fromthe processor and the context of the process to be executed must beinstalled on the processor. This act of moving contexts is called a contextswitch.When switching contexts, the old context must be written to thatprocess’s PCB and the PCB must be stored. Then the PCB from the newprocess is read and restored.
This procedure takes time and its efficiencyis dependent on the amount of data in the PCB and how much thehardware assists. For example, some hardware architectures provide formultiple sets of registers and switching contexts simply switches a register set without copying (this is the case, for example, on UltraSPARCarchitectures). Context-switching incurs enough overhead that researchinto how to minimize it is worth the effort.Processes on LinuxExecution on Linux systems is organized around processes. An executingprogram on Linux is a process, characterized by a PCB and given somememory area in which to store data. In Linux, PCBs are called processdescriptors and these descriptors can be very complex.A process in Linux can be in one of the states shown in Figure 4.1.
Inaddition to these states, Linux defines two other process states: an uninterruptible state, where a process cannot be interrupted by other processesor operating system calls, and a zombie state, where a process is waitingfor a parent process to receive notification of the child’s termination. TheAN OVERVIEW OF THE PROCESS MODEL75uninterruptible state is rarely used, but is useful when a process initiatesan action that must run to completion.
For example, if a device drivertakes a long time to initialize a device, it might need to run to completionand ignore any interruption (which would cause it to lose contact withthe device it is initializing).Processes in Linux are identified by a 32-bit integer. Even thoughprocess IDs (PIDs) are stored as 32 bits, Linux maintains backwardscompatibility with older versions and only uses PIDs up to 32 767 (i.e.,the largest 16-bit integer).