Synchronization in PHP - An Example

by raja 2009-08-28 12:19:30

This works in linux platform only. PHP doesn't have synchronization constructs like Java. This is a workaround.

For this to work, php should be compiled with the option --enable-sysvsem, --enable-sysvshm and --enable-sysvmsg. This works with XAMPP default installation.

Suppose there are two programs each wants to access a shared data namely 1(1 is the name of the variable).

But Only one program is supposed to access it at a time. If the second program wants to access the data it should be blocked. That is it should wait for the first program to finish operation with that data. Then second program can access it.

Here, there are two programs.

The first one, SemaphoreMain.php

<?php

$MEMSIZE = 512;// size of shared memory to allocate
$SEMKEY = 1; // Semaphore key
$SHMKEY = 2; // Shared memory key

echo "Start.
";
// Get semaphore
$sem_id = sem_get($SEMKEY, 1);
if ($sem_id === false)
{
echo "Fail to get semaphore";
exit;
}
else
echo "Got semaphore $sem_id.
";

// Accuire semaphore
if (! sem_acquire($sem_id))
{
echo "Fail to aquire semaphore $sem_id.
";
sem_remove($sem_id);
exit;
}
else
echo "Success aquire semaphore $sem_id.
";

$shm_id = shm_attach($SHMKEY, $MEMSIZE);
if ($shm_id === false)
{
echo "Fail to attach shared memory.
";
sem_remove($sem_id);
exit;
}
else
echo "Success to attach shared memory : $shm_id.
";

// Write variable 1
if (!shm_put_var($shm_id, 1, "Variable 1"))
{
echo "Fail to put var 1 on shared memory $shm_id.
";
sem_remove($sem_id);
shm_remove ($shm_id);
exit;
}
else
echo "Write var1 to shared memory.
";


// Read variable 1
$var1 = shm_get_var ($shm_id, 1);
if ($var1 === false)
{
echo "Fail to retrive Var 1 from Shared memory $shm_id, return value=$var1.
";
}
else
echo "Read var1=$var1.
";

flush();

sleep(60);


// Release semaphore
if (!sem_release($sem_id))
echo "Fail to release $sem_id semaphore.
";
else
echo "Semaphore $sem_id released.
";

flush();

sleep(10); // To give time to Semaphore2.php to finish

// remove shared memory segmant from SysV
if (shm_remove ($shm_id))
echo "Shared memory successfully removed from SysV.
";
else
echo "Fail to remove $shm_id shared memory from SysV.
";

// Remove semaphore
if (sem_remove($sem_id))
echo "semaphore removed successfully from SysV.
";
else
echo "Fail to remove $sem_id semaphore from SysV.
";
echo "End.
";



?>

The Second one, Semaphore2.php

<?php

$MEMSIZE = 512;// size of shared memory to allocate
$SEMKEY = 1; // Semaphore key
$SHMKEY = 2; // Shared memory key

echo "Start.
";
flush();
// Get semaphore
$sem_id = sem_get($SEMKEY, 1);
if ($sem_id === false)
{
echo "Fail to get semaphore";
exit;
}
else
echo "Got semaphore $sem_id.
";
flush();

// Accuire semaphore
if (! sem_acquire($sem_id))
{
echo "Fail to aquire semaphore $sem_id.
";
sem_remove($sem_id);
exit;
}
else
echo "Success aquire semaphore $sem_id.
";
flush();

$shm_id = shm_attach($SHMKEY, $MEMSIZE);
if ($shm_id === false)
{
echo "Fail to attach shared memory.
";
sem_remove($sem_id);
exit;
}
else
echo "Success to attach shared memory : $shm_id.
";


// Read variable 1
$var1 = shm_get_var ($shm_id, 1);
if ($var1 === false)
{
echo "Fail to retrive Var 1 from Shared memory $shm_id, return value=$var1.
";
}
else
echo "Read var1=$var1.
";



// Release semaphore
if (!sem_release($sem_id))
echo "Fail to release $sem_id semaphore.
";
else
echo "Semaphore $sem_id released.
";



?>

Just save these two files and run the SemaphoreMain.php first in your browser or command prompt.
Then run the second file Semaphore2.php immediately within 60 secs because SemaphoreMain.php holds the semaphore for 60 secs.

The output is flushed so you can see how it works.

Here second file waits for the first program to release the semaphore. Then after getting the semaphore it finishes its task.

Similarly one can have many programs liks Semaphore2.php and run immediately. At any point only one program is able to get the semaphore and access the variable 1.

Thanks.

Tagged in:

5099
like
0
dislike
0
mail
flag

You must LOGIN to add comments