Semaphore.st
changeset 4437 212260fce312
parent 3836 318f7d6f242b
child 4633 b6908af8f900
equal deleted inserted replaced
4436:318297e533a6 4437:212260fce312
    55     under some condition.
    55     under some condition.
    56     See 'Processor>>signal:afterSeconds:', 'Processor>>signal:onInput:' etc.
    56     See 'Processor>>signal:afterSeconds:', 'Processor>>signal:onInput:' etc.
    57 
    57 
    58     See examples in doc/coding (found in the CodingExamples-nameSpace).
    58     See examples in doc/coding (found in the CodingExamples-nameSpace).
    59 
    59 
       
    60     Warning/Note/Hint:
       
    61         a Semaphore-forMutualExclusion does NEVER allow for the critical
       
    62         region to be entered twice - NOT EVEN by the same process.
       
    63         That means, that a recursive attempt to enter that section leads
       
    64         to a deadlock.
       
    65         Use a RecursionLock instead of a semaphore to avoid this.
       
    66 
       
    67 
    60     [instance variables:]
    68     [instance variables:]
    61 	count                   <SmallInteger>          the number of waits, that will go through
    69         count                   <SmallInteger>          the number of waits, that will go through
    62 							without blocking.
    70                                                         without blocking.
    63 							Incremented on #signal; decremented on #wait.
    71                                                         Incremented on #signal; decremented on #wait.
    64 
    72 
    65 	waitingProcesses        <OrderedCollection>     waiting processes - will be served first
    73         waitingProcesses        <OrderedCollection>     waiting processes - will be served first
    66 							come first served when signalled.
    74                                                         come first served when signalled.
    67 
    75 
    68 	lastOwnerID             <SmallInteger>          a debugging aid: set when count drops
    76         lastOwnerID             <SmallInteger>          a debugging aid: set when count drops
    69 							to zero to the current processes id.
    77                                                         to zero to the current processes id.
    70 							Helps in finding deadlocks.
    78                                                         Helps in finding deadlocks.
    71 
    79 
    72 	name                    <String>                a debugging aid: an optional userFriendly
    80         name                    <String>                a debugging aid: an optional userFriendly
    73 							name; helps to identify a semaphore easier.
    81                                                         name; helps to identify a semaphore easier.
    74 
    82 
    75     [see also:]
    83     [see also:]
    76 	SemaphoreSet RecursionLock Monitor
    84         SemaphoreSet RecursionLock Monitor
    77 	SharedQueue Delay 
    85         SharedQueue Delay 
    78 	Process ProcessorScheduler
    86         Process ProcessorScheduler
    79 
    87 
    80     [author:]
    88     [author:]
    81 	Claus Gittinger
    89         Claus Gittinger
    82 "
    90 "
    83 !
    91 !
    84 
    92 
    85 examples
    93 examples
    86 "
    94 "
    87     two processes synchronizing on a sema:
    95     two processes synchronizing on a sema:
    88 							[exBegin]
    96                                                         [exBegin]
    89 	|sema thread1 thread2|
    97         |sema thread1 thread2|
    90 
    98 
    91 	sema := Semaphore new.
    99         sema := Semaphore new.
    92 
   100 
    93 	thread1 := [
   101         thread1 := [
    94 			Transcript showCR:'here is thread 1; now waiting ...'.
   102                         Transcript showCR:'here is thread 1; now waiting ...'.
    95 			sema wait.
   103                         sema wait.
    96 			Transcript showCR:'here is thread 1 again.'.
   104                         Transcript showCR:'here is thread 1 again.'.
    97 		   ] newProcess.
   105                    ] newProcess.
    98 
   106 
    99 	thread2 := [
   107         thread2 := [
   100 			Transcript showCR:'here is thread 2; delaying a bit ...'.
   108                         Transcript showCR:'here is thread 2; delaying a bit ...'.
   101 			Delay waitForSeconds:5.
   109                         Delay waitForSeconds:5.
   102 			Transcript showCR:'here is thread 2 again; now signalling the sema'.
   110                         Transcript showCR:'here is thread 2 again; now signalling the sema'.
   103 			sema signal.
   111                         sema signal.
   104 			Transcript showCR:'here is thread 2 after the signalling.'.
   112                         Transcript showCR:'here is thread 2 after the signalling.'.
   105 		  ] newProcess.
   113                   ] newProcess.
   106 
   114 
   107 	thread1 priority:7.
   115         thread1 priority:7.
   108 	thread2 priority:6.
   116         thread2 priority:6.
   109 
   117 
   110 	thread1 resume.
   118         thread1 resume.
   111 	thread2 resume.
   119         thread2 resume.
   112 							[exEnd]
   120                                                         [exEnd]
   113 
   121 
   114     semaphore for critical regions:
   122     semaphore for critical regions:
   115 							[exBegin]
   123                                                         [exBegin]
   116 	|accessLock|
   124         |accessLock|
   117 
   125 
   118 	accessLock := Semaphore forMutualExclusion.
   126         accessLock := Semaphore forMutualExclusion.
   119 
   127 
   120 	[
   128         [
   121 	    5 timesRepeat:[
   129             5 timesRepeat:[
   122 		Delay waitForSeconds:2.
   130                 Delay waitForSeconds:2.
   123 		accessLock critical:[
   131                 accessLock critical:[
   124 		    Transcript showCR:'thread1 in critical region'.
   132                     Transcript showCR:'thread1 in critical region'.
   125 		    Delay waitForSeconds:1.
   133                     Delay waitForSeconds:1.
   126 		    Transcript showCR:'thread1 leaving critical region'.
   134                     Transcript showCR:'thread1 leaving critical region'.
   127 		].
   135                 ].
   128 	    ]
   136             ]
   129 	] forkAt:5.
   137         ] forkAt:5.
   130 
   138 
   131 	[
   139         [
   132 	    5 timesRepeat:[
   140             5 timesRepeat:[
   133 		Delay waitForSeconds:1.
   141                 Delay waitForSeconds:1.
   134 		accessLock critical:[
   142                 accessLock critical:[
   135 		    Transcript showCR:'thread2 in critical region'.
   143                     Transcript showCR:'thread2 in critical region'.
   136 		    Delay waitForSeconds:2.
   144                     Delay waitForSeconds:2.
   137 		    Transcript showCR:'thread2 leaving critical region'.
   145                     Transcript showCR:'thread2 leaving critical region'.
   138 		].
   146                 ].
   139 	    ]
   147             ]
   140 	] forkAt:4.
   148         ] forkAt:4.
   141 							[exEnd]
   149                                                         [exEnd]
       
   150 
       
   151     a deadlock due to recursive enter of a critical region:
       
   152                                                         [exBegin]
       
   153         |accessLock block|
       
   154 
       
   155         accessLock := Semaphore forMutualExclusion.
       
   156 
       
   157         block := [:arg |
       
   158                     Transcript showCR:'about to enter'.
       
   159                     accessLock critical:[
       
   160                         Transcript showCR:'entered - doing action'.
       
   161                         arg value
       
   162                     ].
       
   163                     Transcript showCR:'left region'.
       
   164                  ].
       
   165 
       
   166         block value:[].                 'this works'.
       
   167         block value:[block value:[] ].  'this deadlocks'.
       
   168                                                         [exEnd]
       
   169 
       
   170     Avoid the deadlock by using a RecursionLock instead:
       
   171                                                         [exBegin]
       
   172         |accessLock block|
       
   173 
       
   174         accessLock := RecursionLock new.
       
   175 
       
   176         block := [:arg |
       
   177                     Transcript showCR:'about to enter'.
       
   178                     accessLock critical:[
       
   179                         Transcript showCR:'entered - doing action'.
       
   180                         arg value
       
   181                     ].
       
   182                     Transcript showCR:'left region'.
       
   183                  ].
       
   184 
       
   185         block value:[].                 'this works'.
       
   186         block value:[block value:[] ].  'this deadlocks'.
       
   187                                                         [exEnd]
   142 "
   188 "
   143 ! !
   189 ! !
   144 
   190 
   145 !Semaphore class methodsFor:'instance creation'!
   191 !Semaphore class methodsFor:'instance creation'!
   146 
   192 
   147 forMutualExclusion
   193 forMutualExclusion
   148     "create & return a new semaphore which allows exactly one process to
   194     "create & return a new semaphore which allows exactly one process to
   149      wait on it without blocking. This type of semaphore is used
   195      wait on it without blocking. This type of semaphore is used
   150      for mutual exclusion from critical regions (see #critical:)"
   196      for mutual exclusion from critical regions (see #critical:).
       
   197      Also see RecursionLock, to avoid deadlock in case of recursive entered
       
   198      critical regions."
   151 
   199 
   152     ^ super new setCount:1; name:'criticalRegionSema'
   200     ^ super new setCount:1; name:'criticalRegionSema'
   153 
   201 
   154     "Modified: / 17.6.1998 / 16:23:09 / cg"
   202     "Modified: / 17.6.1998 / 16:23:09 / cg"
   155 !
   203 !
   659 ! !
   707 ! !
   660 
   708 
   661 !Semaphore class methodsFor:'documentation'!
   709 !Semaphore class methodsFor:'documentation'!
   662 
   710 
   663 version
   711 version
   664     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.53 1998-09-14 09:58:08 cg Exp $'
   712     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.54 1999-07-23 07:53:57 cg Exp $'
   665 ! !
   713 ! !