|
280 | 280 |
|
281 | 281 | \begin{itemize} |
282 | 282 | \item \label{LOCK_UNLOCK} The key is the \texttt{O\_EXCL} flag. |
| 283 | +\item Because the exclusive flag is not accessible in most shells, the shell |
| 284 | +scripts usually use \texttt{mkdir} or \texttt{ln} (hard link) commands for |
| 285 | +lock file synchronization. |
283 | 286 | \item example: \example{file-locking/lock-unlock.c} -- it is to be used together |
284 | 287 | with the \example{file-locking/run.sh} shell script. |
285 | 288 | \item In case of process crash the locks are not removed and therefore other |
286 | | -processes would wait forever. Thus it is prudent to write PID of the process |
| 289 | +processes would wait forever. Thus it is prudent to write PID of the process |
287 | 290 | that created the lock to the lock file. The process that is waiting for unlock |
288 | 291 | can verify that the process with given PID number exists. If not, it can remove |
289 | 292 | the lock file and retry. User level command that can do this is e.g. |
290 | 293 | \emsl{\texttt{shlock}}(1) (on FreeBSD in \texttt{/usr/ports/sysutils/shlock}), |
291 | | -however could cause situation in the following paragraph: |
| 294 | +however could cause this situation: |
| 295 | +\begin{itemize} |
292 | 296 | \item \emsl{watch out:} if multiple processes find out simultaneously that |
293 | | -the process does not exist, it can lead to error. First process deletes the |
294 | | -lock file and creates new one with its PID. Next process does the same, |
295 | | -because the operation of reading file contents and removing it is not atomic. |
296 | | -Now both processes think they acquired the lock. |
297 | | -\item \emsl{Problem:} the \texttt{lock()} function contains active waiting. |
| 297 | +the process does not exist, it can lead to error because the operation of |
| 298 | +reading file contents and removing it is not atomic: |
| 299 | +\begin{enumerate} |
| 300 | +\item process A reads the contents of lock file, checks PID existence |
| 301 | +\item process B reads the contents of lock file, checks PID existence |
| 302 | +\item A deletes the lock file |
| 303 | +\item A creates new lock file with its PID |
| 304 | +\item B deletes the lock file |
| 305 | +\item B creates new lock file with its PID |
| 306 | +\item Now both processes think they acquired the lock. |
| 307 | +\end{enumerate} |
| 308 | +\end{itemize} |
| 309 | +\item Another \emsl{problem} is that the \texttt{lock()} function above contains |
| 310 | +active waiting. |
298 | 311 | This can be solved e.g. so that the process that acquired the lock can open |
299 | 312 | named pipe for writing. Reader processes will enter sleep by reading from the |
300 | 313 | pipe. |
|
0 commit comments