|
728 | 728 | \item will describe: |
729 | 729 | \begin{itemize} |
730 | 730 | \item mutexes |
731 | | -\item conditional variables |
| 731 | +\item condition variables |
732 | 732 | \item read-write locks |
733 | 733 | \end{itemize} |
734 | 734 | \end{itemize} |
|
739 | 739 | \begin{itemize} |
740 | 740 | \item Process synchronization is described on pages |
741 | 741 | \pageref{SYNCHRONIZATION} to \pageref{SYNCHRONIZATIONEND}. |
742 | | -\item By using mutexes and conditional variables it is possible to construct any |
| 742 | +\item By using mutexes and condition variables it is possible to construct any |
743 | 743 | other synchronization model. |
744 | 744 | \item The exact behavior of synchronization primitives is largely determined by |
745 | 745 | the scheduler. It decides which of the threads waiting for releasing a lock |
|
921 | 921 | %%%%% |
922 | 922 |
|
923 | 923 | \begin{slide} |
924 | | -\sltitle{Conditional variables (1)} |
| 924 | +\sltitle{Condition variables (1)} |
925 | 925 | \begin{itemize} |
926 | 926 | \item mutexes provide synchronization for shared data |
927 | | -\item conditional variables pass information about the shared data -- |
| 927 | +\item condition variables pass information about the shared data -- |
928 | 928 | for example that the value has changed |
929 | 929 | \item \dots{}and allows to put threads to sleep and wake them up |
930 | 930 | \item therefore \emsl{each condition variable is always associated |
931 | 931 | with exactly one mutex} |
932 | | -\item one mutex can be associated with multiple conditional variables |
933 | | -\item using mutexes and conditional variables it is possible to construct |
| 932 | +\item one mutex can be associated with multiple condition variables |
| 933 | +\item using mutexes and condition variables it is possible to construct |
934 | 934 | other synchronization primitives -- semaphores, barriers, \dots |
935 | 935 | \end{itemize} |
936 | 936 | \end{slide} |
937 | 937 |
|
938 | 938 | \label{CONDITION_VARIABLES} |
939 | 939 |
|
940 | 940 | \begin{itemize} |
941 | | -\item In other words -- conditional variables are handy in a situation when a |
| 941 | +\item In other words -- condition variables are handy in a situation when a |
942 | 942 | thread needs to test the state of \emsl{shared} data (e.g. number of elements in |
943 | 943 | a queue) and voluntarily put itself to sleep if the state is not as desired. |
944 | 944 | The sleeping thread may be woken up by another thread after the latter |
|
949 | 949 | will be saved anywhere, it is as if it never happened. |
950 | 950 | \item A condition variable, which is an opaque type for the programmer, is not |
951 | 951 | associated with a concrete condition like ``\emph{\texttt{n} is greater than |
952 | | -7}''. A conditional variable may in fact be compared to a flag of a certain |
| 952 | +7}''. A condition variable may in fact be compared to a flag of a certain |
953 | 953 | color; if it is lifted up, it means that the threads waiting for the flag to be |
954 | 954 | raised are informed (= woken up) and may use this information to its own |
955 | 955 | judgment. Some threads may wait for \texttt{n} to be bigger than 7, some other |
|
962 | 962 | that they are woken up whenever the variable changed. If the variable is not |
963 | 963 | equal to 7 the thread must voluntarily put itself to sleep again. As it is |
964 | 964 | explained further, the \emsl{test is necessary to perform after an every |
965 | | -wake-up} even if a dedicated conditional variable is used for every possible |
| 965 | +wake-up} even if a dedicated condition variable is used for every possible |
966 | 966 | state -- it may happen that the system can wake up a sleeping thread (because |
967 | 967 | of various implementation reasons) without any other thread causing this; it is |
968 | 968 | called a \emsl{spurious wakeup}. |
|
976 | 976 | ]]]) |
977 | 977 |
|
978 | 978 | \begin{slide} |
979 | | -\sltitle{Conditional variables (2)} |
| 979 | +\sltitle{Condition variables (2)} |
980 | 980 | \prgchars |
981 | 981 | ifdef([[[NOSPELLCHECK]]], [[[ |
982 | 982 | \funml{int \funnm{pthread\_cond\_init}(\=pthread\_cond\_t *\emph{cond}, |
983 | 983 | \\\>const pthread\_condattr\_t *\emph{attr});} |
984 | 984 | ]]]) |
985 | 985 | \begin{itemize} |
986 | | -\item initializes conditional variable \texttt{cond} with attributes \texttt{attr} |
| 986 | +\item initializes condition variable \texttt{cond} with attributes \texttt{attr} |
987 | 987 | (they are set with the \texttt{pthread\_condattr\_...()} functions), |
988 | 988 | \texttt{NULL} = default. |
989 | 989 | \end{itemize} |
990 | 990 | ifdef([[[NOSPELLCHECK]]], [[[ |
991 | 991 | \texttt{int \funnm{pthread\_cond\_destroy}(pthread\_cond\_t *\emph{cond});} |
992 | 992 | ]]]) |
993 | 993 | \begin{itemize} |
994 | | -\item destroys conditional variable. |
| 994 | +\item destroys condition variable. |
995 | 995 | \end{itemize} |
996 | 996 | ifdef([[[NOSPELLCHECK]]], [[[ |
997 | 997 | \funml{int \funnm{pthread\_cond\_wait}(\=pthread\_cond\_t *\emph{cond}, |
998 | 998 | \\\>pthread\_mutex\_t *\emph{mutex});} |
999 | 999 | ]]]) |
1000 | 1000 | \begin{itemize} |
1001 | | -\item waits on conditional variable until another thread calls |
| 1001 | +\item waits on condition variable until another thread calls |
1002 | 1002 | ifdef([[[NOSPELLCHECK]]], [[[ |
1003 | 1003 | \funnm{pthread\_cond\_signal()} or \funnm{pthread\_cond\_broadcast()}. |
1004 | 1004 | ]]]) |
|
1018 | 1018 | if they are blocked. It is important to perform this under the protection of |
1019 | 1019 | the mutex, to be sure what is the state of the data when calling |
1020 | 1020 | \texttt{pthread\_cond\_wait}. |
1021 | | -\item The conditional variables API works thanks to the fact that when entering |
| 1021 | +\item The condition variables API works thanks to the fact that when entering |
1022 | 1022 | critical section the mutex is locked by the thread and the |
1023 | 1023 | \emsl{\texttt{pthread\_cond\_wait} function will unlock the mutex before putting |
1024 | 1024 | the thread to sleep}. Before exiting from the function the mutex is locked |
1025 | 1025 | again. It may therefore happen that the thread is woken up while waiting on a |
1026 | | -conditional variable and then put to sleep again when hitting a mutex already |
| 1026 | +condition variable and then put to sleep again when hitting a mutex already |
1027 | 1027 | locked by another thread. There is nothing complicated about this, it is merely |
1028 | 1028 | a mutual exclusion of threads in a critical section. |
1029 | 1029 | \end{itemize} |
|
1036 | 1036 | ]]]) |
1037 | 1037 |
|
1038 | 1038 | \begin{slide} |
1039 | | -\sltitle{Conditional variables (3)} |
| 1039 | +\sltitle{Condition variables (3)} |
1040 | 1040 | \prgchars |
1041 | 1041 | ifdef([[[NOSPELLCHECK]]], [[[ |
1042 | 1042 | \texttt{int \funnm{pthread\_cond\_signal}(pthread\_cond\_t *\emph{cond});} |
1043 | 1043 | ]]]) |
1044 | 1044 | \begin{itemize} |
1045 | | -\item wakes up one thread waiting on conditional variable |
| 1045 | +\item wakes up one thread waiting on condition variable |
1046 | 1046 | \texttt{cond}. |
1047 | 1047 | \end{itemize} |
1048 | 1048 | ifdef([[[NOSPELLCHECK]]], [[[ |
1049 | 1049 | \texttt{int \funnm{pthread\_cond\_broadcast}(pthread\_cond\_t *\emph{cond});} |
1050 | 1050 | ]]]) |
1051 | 1051 | \begin{itemize} |
1052 | | -\item wakes all threads waiting on conditional variable |
| 1052 | +\item wakes all threads waiting on condition variable |
1053 | 1053 | \texttt{cond}. |
1054 | 1054 | \end{itemize} |
1055 | 1055 | ifdef([[[NOSPELLCHECK]]], [[[ |
|
1064 | 1064 | \end{slide} |
1065 | 1065 |
|
1066 | 1066 | \begin{itemize} |
1067 | | -\item One conditional variable can be used to announce multiple situations at |
| 1067 | +\item One condition variable can be used to announce multiple situations at |
1068 | 1068 | once -- e.g. when inserting or removing an item to/from a queue. Because of |
1069 | 1069 | this, it is necessary to test the condition the thread is waiting for. Another |
1070 | 1070 | consequence of this is that it is necessary to use a broadcast in such a |
|
1095 | 1095 |
|
1096 | 1096 | \begin{slide} |
1097 | 1097 | \label{CONDVAR_USE} |
1098 | | -\sltitle{Using conditional variables} |
| 1098 | +\sltitle{Using condition variables} |
1099 | 1099 | \begin{alltt} |
1100 | 1100 | pthread\_cond\_t cond; pthread\_mutex\_t mutex; |
1101 | 1101 | ... |
|
0 commit comments