X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b89156b5dbb3c1270452379801a79613cd69bb32..066f3611df971be93b2ec46b82c2f05f3ff9a422:/docs/latex/wx/mutex.tex diff --git a/docs/latex/wx/mutex.tex b/docs/latex/wx/mutex.tex index 9b992c4509..85b07b7ae8 100644 --- a/docs/latex/wx/mutex.tex +++ b/docs/latex/wx/mutex.tex @@ -1,41 +1,123 @@ \section{\class{wxMutex}}\label{wxmutex} -A wxMutex controls mutual exclusion, to prevent two or more threads accessing -the same piece of code. +A mutex object is a synchronization object whose state is set to signaled when +it is not owned by any thread, and nonsignaled when it is owned. Its name comes +from its usefulness in coordinating mutually-exclusive access to a shared +resource as only one thread at a time can own a mutex object. + +Mutexes may be recursive in the sense that a thread can lock a mutex which it +had already locked before (instead of dead locking the entire process in this +situation by starting to wait on a mutex which will never be released while the +thread is waiting) but using them is not recommended and they are {\bf not} +recursive by default. The reason for this is that recursive mutexes are not +supported by all Unix flavours and, worse, they cannot be used with +\helpref{wxCondition}{wxcondition}. + +For example, when several threads use the data stored in the linked list, +modifications to the list should only be allowed to one thread at a time +because during a new node addition the list integrity is temporarily broken +(this is also called {\it program invariant}). + +\wxheading{Example} + +{\small% +\begin{verbatim} + // this variable has an "s_" prefix because it is static: seeing an "s_" in + // a multithreaded program is in general a good sign that you should use a + // mutex (or a critical section) + static wxMutex *s_mutexProtectingTheGlobalData; + + // we store some numbers in this global array which is presumably used by + // several threads simultaneously + wxArrayInt s_data; + + void MyThread::AddNewNode(int num) + { + // ensure that no other thread accesses the list + s_mutexProtectingTheGlobalList->Lock(); + + s_data.Add(num); + + s_mutexProtectingTheGlobalList->Unlock(); + } + + // return true if the given number is greater than all array elements + bool MyThread::IsGreater(int num) + { + // before using the list we must acquire the mutex + wxMutexLocker lock(s_mutexProtectingTheGlobalData); + + size_t count = s_data.Count(); + for ( size_t n = 0; n < count; n++ ) + { + if ( s_data[n] > num ) + return false; + } + + return true; + } +\end{verbatim} +} + +Notice how wxMutexLocker was used in the second function to ensure that the +mutex is unlocked in any case: whether the function returns true or false +(because the destructor of the local object {\it lock} is always called). Using +this class instead of directly using wxMutex is, in general safer and is even +more so if your program uses C++ exceptions. + +\wxheading{Constants} + +\begin{verbatim} +enum wxMutexType +{ + // normal mutex: try to always use this one + wxMUTEX_DEFAULT, + + // recursive mutex: don't use these ones with wxCondition + wxMUTEX_RECURSIVE +}; +\end{verbatim} \wxheading{Derived from} None. +\wxheading{Include files} + + + +\wxheading{Library} + +\helpref{wxBase}{librarieslist} + \wxheading{See also} -\helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition} +\helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition}, +\helpref{wxMutexLocker}{wxmutexlocker}, \helpref{wxCriticalSection}{wxcriticalsection} \latexignore{\rtfignore{\wxheading{Members}}} -\membersection{wxMutex::wxMutex}\label{wxmutexconstr} -\func{}{wxMutex}{\void} +\membersection{wxMutex::wxMutex}\label{wxmutexctor} + +\func{}{wxMutex}{\param{wxMutexType }{type = {\tt wxMUTEX\_DEFAULT}}} Default constructor. -\membersection{wxMutex::\destruct{wxMutex}} + +\membersection{wxMutex::\destruct{wxMutex}}\label{wxmutexdtor} \func{}{\destruct{wxMutex}}{\void} Destroys the wxMutex object. -\membersection{wxMutex::IsLocked}\label{wxmutexislocked} - -\constfunc{bool}{IsLocked}{\void} - -Returns TRUE if the mutex is locked, FALSE otherwise. \membersection{wxMutex::Lock}\label{wxmutexlock} \func{wxMutexError}{Lock}{\void} -Locks the mutex object. +Locks the mutex object. This is equivalent to +\helpref{LockTimeout}{wxmutexlocktimeout} with infinite timeout. \wxheading{Return value} @@ -43,11 +125,29 @@ One of: \twocolwidtha{7cm} \begin{twocollist}\itemsep=0pt -\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} -\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} -\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.} +\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} +\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} \end{twocollist} + +\membersection{wxMutex::LockTimeout}\label{wxmutexlocktimeout} + +\func{wxMutexError}{LockTimeout}{\param{unsigned long}{ msec}} + +Try to lock the mutex object during the specified time interval. + +\wxheading{Return value} + +One of: + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{Mutex successfully locked.} +\twocolitem{{\bf wxMUTEX\_TIMEOUT}}{Mutex couldn't be acquired before timeout expiration.} +\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} +\end{twocollist} + + \membersection{wxMutex::TryLock}\label{wxmutextrylock} \func{wxMutexError}{TryLock}{\void} @@ -60,11 +160,11 @@ One of: \twocolwidtha{7cm} \begin{twocollist}\itemsep=0pt -\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} -\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} -\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.} +\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} +\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.} \end{twocollist} + \membersection{wxMutex::Unlock}\label{wxmutexunlock} \func{wxMutexError}{Unlock}{\void} @@ -77,10 +177,7 @@ One of: \twocolwidtha{7cm} \begin{twocollist}\itemsep=0pt -\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} -\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} -\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.} -\twocolitem{{\bf MUTEX\_UNLOCKED}}{The calling thread tries to unlock an unlocked mutex.} +\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.} +\twocolitem{{\bf wxMUTEX\_UNLOCKED}}{The calling thread doesn't own the mutex.} \end{twocollist} -