Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux concurrency scripting with mutexes

On my Linux server, I need to synchronize multiple scripts, written in BASH and PHP, so that only one of them is able to start a system-critical job, which is a series of BASH/PHP commands, that would mess things up if performed simultaneously by two or more scripts. From my experience with multithreading in C++, I'm familiar with the notion of mutex, but how do I implement a mutex for a bunch of scripts that run in separate processes and, of course, aren't written in C++?

Well, the first solution that comes into mind would be making sure that each of the scripts initially creates a "lock flag" file to let other scripts know that the job is "locked" and then deletes the file after it's done with the job. But, as I see it, the file writing and reading operations are required to be completely atomic to let this approach work out with a 100% probability, and the same requirement would apply to any other synchronization method. And I'm pretty sure that file writing/reading operations are not atomic, they are not atomic across all existing Linux/Unix systems at least.

So what is the most flexible and reliable way to synchronize concurrent BASH and PHP scripts?

like image 397
Desmond Hume Avatar asked Nov 07 '12 11:11

Desmond Hume


2 Answers

I'm not a PHP programmer, but the documentation says it provides a portable version of flock that you can use. The first example snippet looks pretty close to what you want. Try this:

<?php

$fp = fopen("/tmp/lock.txt", "r+");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock

    // Do your critical section here, while you hold the lock

    flock($fp, LOCK_UN);    // release the lock
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

?>

Note that by default flock waits until it can acquire the lock. You can use LOCK_EX | LOCK_NB if you want it to exit immediately in the case where another copy of the program is already running.

Using the name "/tmp/lock.txt" may be a security hole (I don't want to think hard enough to decide whether it truly is) so you should probably choose a directory that can only be written to by your program.

like image 172
Jamey Sharp Avatar answered Oct 23 '22 05:10

Jamey Sharp


You can use flock to atomically lock your flag file. The -e option is to acquire an exclusive lock.

From the man page:

By default, if the lock cannot be immediately acquired, flock waits until the lock is available.

So if all your bash/php scripts try to lock the file exclusively, only one can successfully acquire it and rest of them would wait for the lock.

If you don't want to wait thenuse -w to timeout.

like image 20
P.P Avatar answered Oct 23 '22 07:10

P.P