3

I've found similar questions here on Stack but I'm not sure whether they apply to PHP.

I'd like to create child processes with pcntl_fork(). I want to write messages to a log file, from both the parent and the child processes.

If I open a file handle in the parent, is it safe to write to the same handle from the childs? Note that I will only be appending to the file.

I'm afraid of the race conditions that could happen, in particular if the two processes are executed on different cores: what would happen if two processes executing on two different cores were to write to the same file handle at the same time?

Community
  • 1
  • 1
BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • have you considered `Thread` and `Mutex` – Baba Jun 08 '13 at 09:28
  • @Baba No I haven't, actually I wasn't aware of these classes, however I'm not comfortable using them in a production environment, as the `pthreads` extension is beta (current version 0.0.44), and not readily available as an RPM package. Anyway, does that mean that it's not safe to do it without some kind of mutex? – BenMorel Jun 08 '13 at 14:47
  • Try 'n Error! Use flock or: dont use a file descriptor, use a stream to syslog or similiar. Stresstesting this might not be difficult, what you think. or use databases. files and I/O are oldschool – Daniel W. Jun 09 '13 at 20:23
  • @Benjamin it can be safely shared ... and using pthreads in production and its working perfectly fine ... Even with `flock` you can encore only once process is accessing the file as demonstrated : http://stackoverflow.com/a/16998949/1226894 – Baba Jun 09 '13 at 22:06
  • Actually I just realized that `flock()` operated on a resource, and not on a file name! Which makes it perfect to allow two processes to share the same handle (each if them can lock the resource when they need to write to it). Just out of interest, what would happen if we didn't use `flock()`? Would `fwrite()` calls from different processes be serialized anyway, even if they're happening at the same time, or could some weird error happen? – BenMorel Jun 10 '13 at 10:39
  • @Baba You can add your comment as an answer, by the way, your answer on the other question explains it pretty well! – BenMorel Jun 10 '13 at 10:42

1 Answers1

3

Use flock or streamWrapper::stream_lock as the case may be or stream_set_blocking

flock() allows you to perform a simple reader/writer model which can be used on virtually every platform (including most Unix derivatives and even Windows).

flock works on file resource and is closed automatically if fclose() even if the file is not unlocked.

flock($fp, LOCK_EX);

You can loop and wait until the file is ready to be opened for writing in my case am using c+

while(! $fp = @fopen($this->file, "c+")) {
    if (time() - $time > $this->timeout)
        throw new Exception("File can not be accessed");
    usleep(100000);
}

$this->timeout is basically how long you ended to wait for the file a good example can be found PHP issues using flock - file locking

Community
  • 1
  • 1
Baba
  • 94,024
  • 28
  • 166
  • 217