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