PHP Inter-process communication detailed

Source: Internet
Author: User
Tags message queue posix semaphore sigint signal signal handler
A process is a run-time activity of a program with independent functionality about a data collection. In other words, when the system is scheduling multiple CPUs, a basic unit of the program. The process is not an unfamiliar concept for most languages, as the "best language in the world PHP" is certainly the exception.

Environment

The process in PHP is done in the form of an extension. With these extensions, we can easily complete a series of actions on the process.

    • PCNTL Extension: The main process extension, the completion process is created in the wait operation.

    • POSIX extensions: Complete POSIX-compatible generic APIs such as Get process ID, kill process, etc.

    • SYSVMSG extension: A message queue that implements inter-process communication in System V mode.

    • Sysvsem extension: Implements the signal volume in System V mode.

    • SYSVSHM Extension: Implement System V-mode shared memory.

    • Sockets extension: Implements socket communication.

These extensions can only be used in Linux/mac, which is not supported under window. Finally, PHP version 5.5 + is recommended.

A simple example

A simple PHP multi-process example, in this example, a child process, a parent process. The child process outputs 5 times and exits the program.

$parentPid = Posix_getpid (); echo "Parent Progress pid:{$parentPid}\n"; $childList = Array (); $pid = Pcntl_fork (); if ($pid = =-1) {    //Create failed    exit ("fork Progress error!\n");} else if ($pid = = 0) {    //Sub-Process Execution program    $pid = Posix_getpid (); 
   $repeatNum = 5;    for ($i = 1; $i <= $repeatNum; $i + +) {        echo "({$pid}) progress is running! {$i} \ n ";        $rand = rand (1,3);        Sleep ($rand);    }    Exit ("({$pid}) Child Progress end!\n");} else {    //The parent process executes the program    $childList [$pid] = 1;} Wait for the child process to end pcntl_wait ($status); echo "({$parentPid}) main Progress end!";

Perfect, and finally creates a child process, a parent process. Are you done? No, each process is independent of each other, without any intersection, the scope of use is severely affected by the present. What to do, which is interprocess communication (interprogress communication) chant.

Iv. Inter-process communication (IPC)

Typically, processes in Linux communicate in the following ways: Message Queuing, semaphores, shared memory, signals, pipelines, sockets.

1. Message Queuing

Message Queuing is a queue that is stored in memory. The following code will create 3 producer child processes, 2 consumer subprocess. These 5 processes will communicate through Message Queuing.

$parentPid = Posix_getpid (); echo "Parent Progress pid:{$parentPid}\n"; $childList = Array ();//Create Message queue, and define message type ( Similar to a library in a database) $id = Ftok (__file__, ' m '); $msgQueue = Msg_get_queue ($id); Const MSG_TYPE = 1;//producer function producer () {Global    $msgQueue;    $pid = Posix_getpid ();    $repeatNum = 5; for ($i = 1; $i <= $repeatNum; $i + +) {$str = "({$pid}) Progress create!        {$i} ";        Msg_send ($msgQueue, Msg_type, $STR);        $rand = rand (1,3);    Sleep ($rand);    }}//Consumer Function consumer () {Global $msgQueue;    $pid = Posix_getpid ();    $repeatNum = 6;        for ($i = 1; $i <= $repeatNum; $i + +) {$rel = Msg_receive ($msgQueue, Msg_type, $msgType, 1024x768, $message); echo "{$message} |        Consumer ({$pid}) destroy \ n ";        $rand = rand (1,3);    Sleep ($rand);    }}function createprogress ($callback) {$pid = Pcntl_fork ();    if ($pid = =-1) {//Create failed exit ("fork Progress error!\n"); } else if ($pid = = 0) {//Sub-process Executor $pid = Posix_getpid ();        $callback ();    Exit ("({$pid}) Child Progress end!\n");    }else{//parent process executing program return $pid;    }}//3 Write processes for ($i = 0; $i < 3; $i + +) {$pid = createprogress (' producer ');    $childList [$pid] = 1; echo "Create producer child progress: {$pid} \ n";}    2 Write processes for ($i = 0; $i < 2; $i + +) {$pid = createprogress (' consumer ');    $childList [$pid] = 1; echo "Create consumer child progress: {$pid} \ n";}    Wait for all child processes to end while (!empty ($childList)) {$childPid = pcntl_wait ($status);    if ($childPid > 0) {unset ($childList [$childPid]); }}echo "({$parentPid}) main Progress end!\n";

Because the message queue goes to the data, only one process can go, so no additional locks or semaphores are required.

2. semaphores and Shared memory

Semaphore: is an atomic operation provided by the system, a semaphore, and only one process can operate. When a process obtains a semaphore, it must be freed by the process.

Shared memory: Is the system in memory open up a piece of public memory area, any process can access, at the same time, there can be more than one process to access the zone, in order to ensure the consistency of the data, the memory area needs to be locked or semaphore.

Following, create multiple processes to modify the same value in memory.

$parentPid = Posix_getpid (); echo "Parent Progress pid:{$parentPid}\n"; $childList = Array (); Create shared memory, create semaphores, define shared key$shm_id = Ftok (__file__, ' m '); $sem _id = Ftok (__file__, ' s '); $shareMemory = Shm_attach ($shm _id); $    Signal = Sem_get ($sem _id); Const Share_key = 1;//producer function producer () {Global $shareMemory;    Global $signal;    $pid = Posix_getpid ();    $repeatNum = 5;         for ($i = 1; $i <= $repeatNum; $i + +) {//Get semaphore Sem_acquire ($signal);            if (Shm_has_var ($shareMemory, Share_key)) {//has a value, plus one $count = Shm_get_var ($shareMemory, Share_key);            $count + +;            Shm_put_var ($shareMemory, Share_key, $count);        echo "({$pid}) Count: {$count}\n";            }else{//No value, initialization of Shm_put_var ($shareMemory, share_key,0);        echo "({$pid}) count:0\n";         }//Run out of release sem_release ($signal);        $rand = rand (1,3);    Sleep ($rand); }}function createprogress ($callback) {$pid = Pcntl_fork ();    if ($pid = =-1) {//Create failed exit ("fork Progress error!\n");        } else if ($pid = = 0) {//Sub-Process Execution Program $pid = Posix_getpid ();        $callback ();    Exit ("({$pid}) Child Progress end!\n");    }else{//parent process executing program return $pid;    }}//3 Write processes for ($i = 0; $i < 3; $i + +) {$pid = createprogress (' producer ');    $childList [$pid] = 1; echo "Create producer child progress: {$pid} \ n";}    Wait for all child processes to end while (!empty ($childList)) {$childPid = pcntl_wait ($status);    if ($childPid > 0) {unset ($childList [$childPid]); }}//releases shared memory and Semaphore Shm_remove ($shareMemory); Sem_remove ($signal); echo "({$parentPid}) main Progress end!\n";

3. Signal

A signal is a system call. Usually we use the KILL command to send a signal to a process. There are specific signals that can be run kill-l view in Liunx/mac. In the following example, the parent process waits 5 seconds to send a SIGINT signal to the child process. The child process captures the signal, and the signal processing function is processed.

$parentPid = Posix_getpid (); echo "Parent Progress pid:{$parentPid}\n"; Defines a signal handler function Sighandler ($signo) {    $pid = Posix_getpid ();    echo "{$pid} Progress,oh No, I ' m killed!\n";    Exit (1);} $pid = Pcntl_fork (), if ($pid = =-1) {    //Create failed    exit ("fork Progress error!\n");} else if ($pid = = 0) {    //Sub-Process execution Program    //Register signal processing function    declare (ticks=10);    Pcntl_signal (SIGINT, "Sighandler");    $pid = Posix_getpid ();    while (true) {        echo ' {$pid} child progress is running!\n ";        Sleep (1);    }    Exit ("({$pid}) Child Progress end!\n");} else{    //Parent Process Execution Program    $childList [$pid] = 1;    After 5 seconds, the parent process sends a SIGINT signal to the child process.    Sleep (5);    Posix_kill ($pid, SIGINT);    Sleep (5);} echo "({$parentPid}) main Progress end!\n";

4. Pipeline (famous pipe)

Pipeline is a more commonly used multi-process communication means, pipelines are divided into nameless pipes and well-known pipelines, nameless pipes can only be used for the relationship between interprocess communication, and a well-known pipeline can be used on the same host on any process. Only the famous pipes are introduced here. In the following example, the child process writes the data, and the parent process reads the data.

Define pipeline path, with Create pipeline $pipe_path = '/data/test.pipe '; if (!file_exists ($pipe _path)) {    if (!posix_mkfifo ($pipe _path,0664) {        exit ("Create pipe error!");}    } $pid = Pcntl_fork (), if ($pid = = 0) {    //Sub-process, write data to pipe    $file = fopen ($pipe _path, ' W ');    while (true) {        fwrite ($file, ' Hello World ');        $rand = rand (1,3);        Sleep ($rand);    }    Exit (' child end! ');} else{    //parent process, read data from pipe    $file = fopen ($pipe _path, ' R ');    while (true) {        $rel = fread ($file);        echo "{$rel}\n";        $rand = rand;        Sleep ($rand);}    }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.