14

How to make functions in PHP synchronized so that same function won't be executed concurrently ? 2nd user must wait till 1st user is done with the function. Then 2nd user can execute the function.

Thanks

0

5 Answers 5

16

This basically comes down to setting a flag somewhere that the function is locked and cannot be executed until the first caller returns from that function. This can be done in a number of ways:

  • use a lock file (first function locks a file name "f.lok", second function checks if the lock file exists and executes or doesn't based on that evaluation)
  • set a flag in the database (not recomended)
  • use semaphores as @JvdBerg suggested (the fastest)

When coding concurrent application always beware of race conditions and deadlocks!

UPDATE using semaphores (not tested):

<?php

define('SEM_KEY', 1000);

function noconcurrency() {
    $semRes = sem_get(SEM_KEY, 1, 0666, 0); // get the resource for the semaphore

    if(sem_acquire($semRes)) { // try to acquire the semaphore. this function will block until the sem will be available
        // do the work 
        sem_release($semRes); // release the semaphore so other process can use it
    }
}

PHP needs to be compiled with sysvsem support in order to use sem_* functions

Here's a more in depth tutorial for using semaphores in PHP:

http://www.re-cycledair.com/php-dark-arts-semaphores

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the support. BTW if you can provide me a code snippet how this is implemented.
Thanks for the PHP code. Let me check that and get back to you
@VladBalmos: "When coding concurrent," you say... isn't everything PHP always concurrent if more than one user visits the site at the same time or am I missing something fundamental?
@Erk You are right. I was referring to the ability to access a resource while it's modified by another user and get consistent data, if it makes sense.
I think a lock file won't work unless PHP is single-threaded. Otherwise, if user A checks the lock file and finds that it is missing, then before A gets a chance to create the lock file, user B could also check the lock file and also find it missing. So both A and B think they can hold the lock and failure happens. Note also that checking whether the lock file is missing should be done by defeating the usual caching of files and directories. So, is PHP single-threaded or not?
|
12

You are looking for a Semaphore

Bear in mind that using a semaphore (or any other blocking mechanism) can have serious peformance issues, as the requests can not be handled while the semaphore is up.

1 Comment

The performance problem is solved by including a timeout. If user B requests a lock but can't get it within half a second, force the lock.
1

You can use the "flock" (file locking) function with the "LOCK_EX" (exclusive lock) flag to create a custom "synchronized" function that accepts a handler to be synchronized.

You may may found the code here.

I hope this helps.

Comments

0

off the top of my head:

  • function checks if a database field called isFunctionRunning is equal 1. if not start executing
  • you update the database field called isFunctionRunning to 1
  • function does magic here
  • you update the database field called isFunctionRunning to 0

but somehow i think what you are trying to do is "wrong" and can be achieved in another way. could help if you said more details

edit: wasn't aware of php semaphores, the answer above will be way faster.

5 Comments

looks like it's not possible to implement through php
what is not possible to implement through php ?
if isFunctionRunning returns 1, How can I tell PHP to wait till isFunctionRunning returns 0
if (isFunctionRunning == 1) { return false; } else { run function run } p.s. instead of updating a db field you could just do that in a file ( would be faster ).
Sorry, I thing that does not work, because in between your first 2 steps, you could get concurrency issues, like 2 threads reading the same 0 from isFunctionRunning and think they are the first. That's why => semaphores.
-1

Unless PHP is single-threaded, and for all server operating systems (see my comments), I think you need a two-phase solution. In phase 1, each process waits for each of two locks, lock1 and lock2, to be free (with timeout), then registers its desire to use the resource by again checking and setting both locks. The checking is done by storing the same random number into both lock files. In phase 2, the process ensures that it still has both locks set, then uses the shared resource, then clears the locks. I haven't tested it, but I'm going to try it.

Note that lock operations have to suspend the usual PHP file caching.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.