]>
Commit | Line | Data |
---|---|---|
1 | \section{\class{wxMutex}}\label{wxmutex} | |
2 | ||
3 | A mutex object is a synchronization object whose state is set to signaled when | |
4 | it is not owned by any thread, and nonsignaled when it is owned. Its name comes | |
5 | from its usefulness in coordinating mutually-exclusive access to a shared | |
6 | resource as only one thread at a time can own a mutex object. | |
7 | ||
8 | Mutexes may be recursive in the sense that a thread can lock a mutex which it | |
9 | had already locked before (instead of dead locking the entire process in this | |
10 | situation by starting to wait on a mutex which will never be released while the | |
11 | thread is waiting) but using them is not recommended under Unix and they are | |
12 | {\bf not} recursive there by default. The reason for this is that recursive | |
13 | mutexes are not supported by all Unix flavours and, worse, they cannot be used | |
14 | with \helpref{wxCondition}{wxcondition}. On the other hand, Win32 mutexes are | |
15 | always recursive. | |
16 | ||
17 | For example, when several threads use the data stored in the linked list, | |
18 | modifications to the list should only be allowed to one thread at a time | |
19 | because during a new node addition the list integrity is temporarily broken | |
20 | (this is also called {\it program invariant}). | |
21 | ||
22 | \wxheading{Example} | |
23 | ||
24 | {\small% | |
25 | \begin{verbatim} | |
26 | // this variable has an "s_" prefix because it is static: seeing an "s_" in | |
27 | // a multithreaded program is in general a good sign that you should use a | |
28 | // mutex (or a critical section) | |
29 | static wxMutex *s_mutexProtectingTheGlobalData; | |
30 | ||
31 | // we store some numbers in this global array which is presumably used by | |
32 | // several threads simultaneously | |
33 | wxArrayInt s_data; | |
34 | ||
35 | void MyThread::AddNewNode(int num) | |
36 | { | |
37 | // ensure that no other thread accesses the list | |
38 | s_mutexProtectingTheGlobalList->Lock(); | |
39 | ||
40 | s_data.Add(num); | |
41 | ||
42 | s_mutexProtectingTheGlobalList->Unlock(); | |
43 | } | |
44 | ||
45 | // return true if the given number is greater than all array elements | |
46 | bool MyThread::IsGreater(int num) | |
47 | { | |
48 | // before using the list we must acquire the mutex | |
49 | wxMutexLocker lock(s_mutexProtectingTheGlobalData); | |
50 | ||
51 | size_t count = s_data.Count(); | |
52 | for ( size_t n = 0; n < count; n++ ) | |
53 | { | |
54 | if ( s_data[n] > num ) | |
55 | return false; | |
56 | } | |
57 | ||
58 | return true; | |
59 | } | |
60 | \end{verbatim} | |
61 | } | |
62 | ||
63 | Notice how wxMutexLocker was used in the second function to ensure that the | |
64 | mutex is unlocked in any case: whether the function returns true or false | |
65 | (because the destructor of the local object {\it lock} is always called). Using | |
66 | this class instead of directly using wxMutex is, in general safer and is even | |
67 | more so if your program uses C++ exceptions. | |
68 | ||
69 | \wxheading{Constants} | |
70 | ||
71 | \begin{verbatim} | |
72 | enum wxMutexType | |
73 | { | |
74 | // normal mutex: try to always use this one | |
75 | wxMUTEX_DEFAULT, | |
76 | ||
77 | // recursive mutex: don't use these ones with wxCondition | |
78 | wxMUTEX_RECURSIVE | |
79 | }; | |
80 | \end{verbatim} | |
81 | ||
82 | \wxheading{Derived from} | |
83 | ||
84 | None. | |
85 | ||
86 | \wxheading{Include files} | |
87 | ||
88 | <wx/thread.h> | |
89 | ||
90 | \wxheading{Library} | |
91 | ||
92 | \helpref{wxBase}{librarieslist} | |
93 | ||
94 | \wxheading{See also} | |
95 | ||
96 | \helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition}, | |
97 | \helpref{wxMutexLocker}{wxmutexlocker}, \helpref{wxCriticalSection}{wxcriticalsection} | |
98 | ||
99 | \latexignore{\rtfignore{\wxheading{Members}}} | |
100 | ||
101 | ||
102 | \membersection{wxMutex::wxMutex}\label{wxmutexctor} | |
103 | ||
104 | \func{}{wxMutex}{\param{wxMutexType }{type = {\tt wxMUTEX\_DEFAULT}}} | |
105 | ||
106 | Default constructor. | |
107 | ||
108 | ||
109 | \membersection{wxMutex::\destruct{wxMutex}}\label{wxmutexdtor} | |
110 | ||
111 | \func{}{\destruct{wxMutex}}{\void} | |
112 | ||
113 | Destroys the wxMutex object. | |
114 | ||
115 | ||
116 | \membersection{wxMutex::Lock}\label{wxmutexlock} | |
117 | ||
118 | \func{wxMutexError}{Lock}{\void} | |
119 | ||
120 | Locks the mutex object. This is equivalent to | |
121 | \helpref{LockTimeout}{wxmutexlocktimeout} with infinite timeout. | |
122 | ||
123 | \wxheading{Return value} | |
124 | ||
125 | One of: | |
126 | ||
127 | \twocolwidtha{7cm} | |
128 | \begin{twocollist}\itemsep=0pt | |
129 | \twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} | |
130 | \twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} | |
131 | \end{twocollist} | |
132 | ||
133 | ||
134 | \membersection{wxMutex::LockTimeout}\label{wxmutexlocktimeout} | |
135 | ||
136 | \func{wxMutexError}{LockTimeout}{\param{unsigned long}{ msec}} | |
137 | ||
138 | Try to lock the mutex object during the specified time interval. | |
139 | ||
140 | \wxheading{Return value} | |
141 | ||
142 | One of: | |
143 | ||
144 | \twocolwidtha{7cm} | |
145 | \begin{twocollist}\itemsep=0pt | |
146 | \twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{Mutex successfully locked.} | |
147 | \twocolitem{{\bf wxMUTEX\_TIMEOUT}}{Mutex couldn't be acquired before timeout expiration.} | |
148 | \twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} | |
149 | \end{twocollist} | |
150 | ||
151 | ||
152 | \membersection{wxMutex::TryLock}\label{wxmutextrylock} | |
153 | ||
154 | \func{wxMutexError}{TryLock}{\void} | |
155 | ||
156 | Tries to lock the mutex object. If it can't, returns immediately with an error. | |
157 | ||
158 | \wxheading{Return value} | |
159 | ||
160 | One of: | |
161 | ||
162 | \twocolwidtha{7cm} | |
163 | \begin{twocollist}\itemsep=0pt | |
164 | \twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} | |
165 | \twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.} | |
166 | \end{twocollist} | |
167 | ||
168 | ||
169 | \membersection{wxMutex::Unlock}\label{wxmutexunlock} | |
170 | ||
171 | \func{wxMutexError}{Unlock}{\void} | |
172 | ||
173 | Unlocks the mutex object. | |
174 | ||
175 | \wxheading{Return value} | |
176 | ||
177 | One of: | |
178 | ||
179 | \twocolwidtha{7cm} | |
180 | \begin{twocollist}\itemsep=0pt | |
181 | \twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} | |
182 | \twocolitem{{\bf wxMUTEX\_UNLOCKED}}{The calling thread doesn't own the mutex.} | |
183 | \end{twocollist} | |
184 |