Page 357 - DCAP103_Principle of operating system
P. 357

Principles of Operating Systems



                   Notes         Sockets are like pipes, except that they normally connect processes on different machines. For
                                 example, one process writes to a socket and another one on a remote machine reads from it.
                                 Sockets can also be used to connect processes on the same machine, but since they entail more
                                 overhead than pipes, they are generally only used in a networking context.
                                 Remote procedure calls are a way for process A to have process B call a procedure in B’s address
                                 space on A’s behalf and return the result to A. Various restrictions on the parameters exist. For
                                 example, it makes no sense to pass a pointer to a different process.

                                 Finally,  processes  can  share  memory  by  mapping  onto  the  same  file  at  the  same  time.  All
                                 writes done by one process then appear in the address spaces of the other processes. Using this
                                 mechanism, the shared buffer used in producer-consumer problems can easily be implemented.
                                 Just  as  Windows  2000  provides  numerous  interprocess  communication  mechanisms,  it  also
                                 provides numerous synchronization mechanisms, including semaphores, mutexes, critical regions,
                                 and events. All of these mechanisms work on threads, not processes, so that when a thread blocks
                                 on a semaphore, other threads in that process (if any) are not affected and can continue to run.

                                 A  semaphore  is  created  using  the  CreateSemaphore  API  function,  which  can  initialize  it  to
                                 a given value and define a maximum value as well. Semaphores are kernel objects and thus
                                 have security descriptors and handles. The handle for a semaphore can be duplicated using
                                 DuplicateHandle and passed on to another process so that multiple processes can be synchronized
                                 on the same semaphore. Calls for up and down are present, although they have the somewhat
                                 peculiar names of ReleaseSemaphore (up) and WaitForSingleObject (down). It is also possible
                                 to give WaitForSingleObject a timeout, so the calling thread can be released eventually, even if
                                 the semaphore remains at 0 (although timers reintroduce races).
                                 Mutexes  are  also  kernel  objects  used  for  synchronization,  but  simpler  than  semaphores
                                 because they do not have counters. They are essentially locks, with API functions for locking
                                 (WaitForSingleObject) and unlocking (ReleaseMutex). Like semaphore handles, mutex handles
                                 can be duplicated and passed between  processes  so that threads in different processes  can
                                 access the same mutex.
                                 The third synchronization mechanism is based on critical sections, (which we have called critical
                                 regions elsewhere in this site) which are similar to mutexes, except local to the address space of
                                 the creating thread. Because critical sections are not kernel objects, they do not have handles or
                                 security descriptors and cannot be passed between processes. Locking and unlocking is done
                                 with EnterCriticalSection and LeaveCriticalSection, respectively. Because these API functions
                                 are performed initially in user space and only make kernel calls when blocking is needed, they
                                 are faster than mutexes.
                                 The last synchronization mechanism uses kernel objects called events of which there are two
                                 kinds—manual-reset events and  auto-reset events. Any event can be in one of two states;
                                 set and cleared. A thread can wait for an event to occur with WaitForSingleObject. If another
                                 thread signals an event with SetEvent, what happens depends on the type of event. With a
                                 manual-reset  event,  all  waiting  threads  are  released  and  the  event  stays  set  until  manually
                                 cleared with ResetEvent. With an auto-reset event, if one or more threads are waiting, exactly
                                 one thread is released and the event is cleared. An alternative operation is PulseEvent, which
                                 is like SetEvent except that if nobody is waiting, the pulse is lost and the event is cleared. In
                                 contrast, a SetEvent that occurs with no waiting threads is remembered by leaving the event in
                                 set state so a subsequent thread waiting on it is released immediately.
                                 Events, mutexes, and semaphores can all be named and stored in the file system, like named
                                 pipes.  Two  or  more  processes  can  be  synchronized  by  opening  the  same  event,  mutex,  or



        350                               LOVELY PROFESSIONAL UNIVERSITY
   352   353   354   355   356   357   358   359   360   361   362