当前位置:网站首页>PHP interprocess pass file descriptor

PHP interprocess pass file descriptor

2022-06-25 23:47:00 ndrandy

  What are the practical application scenarios for passing file descriptors between processes ?


-   Recently I saw golang Server smooth hot restart reload when , Need long links not to be broken , need fork A sub process comes out , Then all of the parent process socket The file of The descriptor ( namely : all hold Client connections for ) Are passed to the child process . No research linux Before passing file descriptors between processes , All I have in mind is fork when , happen copy-on-write, The parent and child processes can share the connection directly fd 了 , But at this point , If the parent process exits , All the connections were cut off , Because the parent and child processes share the connection resources . So we need to fd The associated resources are complete clone Into child processes , Make the parent-child process correspond to fd Completely divorced , however fd From the parent process copy After the child process , to want to fd value (int) All in line , Is unlikely to , Because the child process needs to be reallocated fd Of .
 

 

How to implement interprocess transfer fd Well ?

- Probably through unixsockt, one end sendmsg, The other end recvmsg, But it is not a simple transmission of message content , You need to tell the kernel that the file descriptor is transferred  SCM_RIGHTS. Let's go straight to php Version of demo

<?php

$fds = [];
$ret = socket_create_pair(AF_UNIX, SOCK_DGRAM, 0, $fds);
if (!$ret) {
    exit(socket_strerror(socket_last_error()));
}
$pid = pcntl_fork();
if ($pid > 0) {
    socket_close($fds[0]);
    $handle = fopen(__DIR__ . '/atomic.txt', 'a+');
    var_dump($handle);
    socket_sendmsg($fds[1], [
        'control' => [
            [
                'level' => SOL_SOCKET,
                'type'  => SCM_RIGHTS,
                'data'  => [$handle]
            ]
        ]
    ], 0);
    sleep(1);
} else {
    socket_close($fds[1]);
    $data = [
        'controllen' => socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, 1)
    ];
    $result = socket_recvmsg($fds[0], $data, 0);
    var_dump("recv ok\n");
    var_dump($data['control'][0]['data'][0]);
    fwrite($data['control'][0]['data'][0], 'passing fd in PHP' . PHP_EOL);
}

In the above code , The parent process var_dump($handle), And subprocesses var_dump($data['control'][0]['data'][0]); Twice printed resource The resource type int The value has changed , explain fd It's complete clone In the past , The parent process exits , It will not affect the subprocess fd 了 .

原网站

版权声明
本文为[ndrandy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206252056449730.html