Author:halw

Date:2008-12-01T22:45:08.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@112 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
halw
2008-12-01 22:45:08 +00:00
parent 7312cec21e
commit bba0936e07
11 changed files with 282 additions and 252 deletions

View File

@@ -22,25 +22,25 @@ Moreover, an Eiffel programmer should be able to have an alternative between a o
Here is what you will do to implement a once per process feature:
<code>
class
TEST_ONCE_PER_PROCESS
TEST_ONCE_PER_PROCESS
feature -- Access
object_per_thread: OBJECT is
-- Once per thread.
once
create Result.make
end
object_per_thread: OBJECT
-- Once per thread.
once
create Result.make
end
object_per_process: OBJECT is
-- New 'object' (once per process)
-- that could be shared between threads
-- without reinitializing it.
indexing
once_status: global
once
create Result.make
end
object_per_process: OBJECT
-- New 'object' (once per process)
-- that could be shared between threads
-- without reinitializing it.
indexing
once_status: global
once
create Result.make
end
end -- class TEST_ONCE_PER_PROCESS
</code>

View File

@@ -9,23 +9,24 @@ The class of the thread object you want to create should inherit the <eiffel>THR
Your thread is represented by a class which inherits from <eiffel>THREAD</eiffel> (deferred class). <br/>
<code>
class
MY_THREAD
class
MY_THREAD
inherit
THREAD
...
inherit
THREAD
...
feature
feature
execute is
-- define the deferred feature from THREAD.
do
...
end
...
execute
-- define the deferred feature from THREAD.
do
...
end
end -- class MY_THREAD
...
end -- class MY_THREAD
</code>
@@ -33,11 +34,13 @@ Creating a thread is like creating an Eiffel object:
<code>
my_thread: MY_THREAD
-- MY_THREAD inherits from THREAD and defines
-- the deferred procedure `execute'
my_thread: MY_THREAD
-- MY_THREAD inherits from THREAD and defines
-- the deferred procedure `execute'
create my_thread
...
create my_thread
</code>
@@ -45,7 +48,8 @@ Creating a thread is like creating an Eiffel object:
To run the thread, use the feature <eiffel>launch</eiffel> from <eiffel>THREAD</eiffel>. }}
<code> my_thread.launch</code>
<code>
my_thread.launch</code>
On the Eiffel side, the procedure <eiffel>execute</eiffel> will be launched. This procedures deferred in class <eiffel>THREAD</eiffel>, you have to define it in <eiffel>MY_THREAD</eiffel>.
@@ -66,22 +70,28 @@ The implementation of the class <eiffel>MUTEX</eiffel> is mapped on the C standa
* Declaration of the mutex:
<code> my_mutex: MUTEX</code>
<code>
my_mutex: MUTEX</code>
* Creation of mutex:
<code> create my_mutex.make</code>
<code>
create my_mutex.make</code>
* Locking the mutex:
<code> my_mutex.lock</code>
<code>
my_mutex.lock</code>
* Unlocking the mutex:
<code> my_mutex.unlock</code>
<code>
my_mutex.unlock</code>
* <eiffel>try_lock</eiffel>: if it is not locked yet, lock the mutex and return True, otherwise it returns False.
<code> my_mutex.try_lock</code>
<code>
my_mutex.try_lock</code>
* Is my mutex initialized?
<code> my_mutex.is_set</code>
<code>
my_mutex.is_set</code>
{{note|on Windows: The <eiffel>MUTEX</eiffel> objects on Windows are recursive while they are not on Unix. A recursive mutex can be locked twice by the same thread. }}
@@ -96,19 +106,24 @@ Like <eiffel>MUTEX</eiffel>, the features of this class are mapped on the C thre
* Declaration of the semaphore :
<code> my_sem: SEMAPHORE</code>
<code>
my_sem: SEMAPHORE</code>
Creation of semaphore: initialize semaphore with nb_tokens, it requires nb_tokens > = 0
<code> create my_sem.make (nb_tokens)</code>
<code>
create my_sem.make (nb_tokens)</code>
* Wait for a token:
<code> my_sem.wait</code>
<code>
my_sem.wait</code>
* Give back a token:
<code> my_sem.post</code>
<code>
my_sem.post</code>
* <eiffel>try_wait</eiffel>, similar to try_lock from <eiffel>MUTEX</eiffel>, if a token is available, take it and return <code> True </code>, otherwise return <code> False </code>.
<code> my_sem.try_wait</code>
<code>
my_sem.try_wait</code>
{{caution|Be sure that a semaphore does not wait for a token when it is disposed }}
@@ -119,38 +134,44 @@ This class allows to use condition variables in Eiffel. An instance of class <ei
* Declaration of the condition variable
<code> my_cond: CONDITION_VARIABLE</code>
<code>
my_cond: CONDITION_VARIABLE</code>
* Creation:
<code> create my_cond.make</code>
<code>
create my_cond.make</code>
* Wait for a signal (send by <eiffel>signal</eiffel>). You need to use a mutex.
<code>
my_mutex: MUTEX
my_mutex: MUTEX
create my_mutex.make
...
create my_mutex.make
</code>
<code>my_mutex </code> must be locked by the calling thread so as <eiffel>wait</eiffel> can be called. <eiffel>wait</eiffel> atomically unlocks <code> my_mutex </code> and waits for the condition variable <code> my_mutex </code> to receive a signal. As soon as it received a signal, ''<code>my_cond </code>'' locks ''<code>my_mutex </code>''
<code>my_mutex</code> must be locked by the calling thread so as <eiffel>wait</eiffel> can be called. <eiffel>wait</eiffel> atomically unlocks <code> my_mutex </code> and waits for the condition variable <code> my_mutex </code> to receive a signal. As soon as it received a signal, ''<code>my_cond </code>'' locks ''<code>my_mutex </code>''
<code>
my_mutex.lock
-- You must lock `my_mutex' before calling wait.
my_mutex.lock
-- You must lock `my_mutex' before calling wait.
my_cond.wait (my_mutex)
-- Here the critical code to execute when `my_cond' received a signal.
my_cond.wait (my_mutex)
-- Here the critical code to execute when `my_cond' received a signal.
my_mutex.unlock
-- Unlock the mutex at the end of the critical section.
my_mutex.unlock
-- Unlock the mutex at the end of the critical section.
</code>
* Send a signal one thread blocked on the condition variable `my_cond'.
<code> my_cond.signal</code>
<code>
my_cond.signal</code>
* Send a signal to all the threads blocked on the condition variable `my_cond'.
<code> my_cond.broadcast</code>
<code>
my_cond.broadcast</code>
{{caution|Be sure that a condition variable is unblocked when it is disposed. }}
@@ -167,11 +188,12 @@ class <eiffel>THREAD_ATTRIBUTES</eiffel>: defines the attributes of an Eiffel Th
* <eiffel>join_all</eiffel>: the calling thread waits for all other threads to finished (all its children).
* A parent thread can wait for the termination of a child process through the feature <eiffel>join</eiffel> of class <eiffel>THREAD_CONTROL</eiffel> (inherited by <eiffel>THREAD</eiffel>):
<code>
thr: MY_THREAD
...
thr.launch
...
thr.join
thr: MY_THREAD
...
thr.launch
...
thr.join
</code>