php sleep函数导致请他请求阻塞

背景

今天在模拟一个导出进度条时, 需要在session中存放当前的导出进度,为了模拟进度,使用sleep增加导出时间,设置导出进度, 然后前端间隔时间去获取进度,但是此时获取进度的所有请求会阻塞,知道sleep函数执行完,获取进度的请求才会返回

原因

默认使用的php的session模式是file模式,也就说会把session存储的值写入到服务器的某个目录下的文件中,文件名是使用hash函数对用户的浏览 器+ip等获取的结果(同一电脑浏览器多次访问,这个值不变),在A请求中,写入session的初始值,此时A请
求占领该文件的写锁,然后A请求进入sleep阻塞状态,当b,c,d等请求(同一电脑浏览器)从session获取进度时,因为session所在的文件被A请求占领,PHP在访问SESSION数据时,首先需要获取到SESSION锁,否则就会sleep一段时间,然后重试。所以这些请求会一直阻塞,一直等到A请求处理完毕,其他请求才会返回。

示例有问题代码

// 前端代码
            function getProgress() { // 获取进度
                $.get(
                        "{:U('/admin/UserScore/getProgress')}",
                        function(data) {
                            if (data == 'ok') {
                                clearInterval(a);
                            }
                        }
                );
            }
            var a = '';
            function getFile() { // 虎丘文件
                $.post(
                        "{:U('/admin/UserScore/getFile')}",
                        function(data) {
                            console.log('success');
                        }
                );

                a = setInterval(getProgress, 1000);
            }
            getFile();
// 后端代码
    public function getProgress() {
        $fileLength = 4
        $result = $_SESSION['status'];
        if ($fileLength == $result) { //获取更新进度
            echo 'ok';
        } else {
            echo 'loading';
        }
    }

    public function getFile() {
        $_SESSION['status'] = 0; //初始化进度
        for ($i=0; $i < 5; $i++) { // 模拟处理,sleep阻塞时间
            sleep(2);
            $_SESSION['status'] = $i;
        }
    }

解决办法:

- getFile函数每次写入session之后就释放写锁即可,每次写入时,在打开session,更改getFile函数如下即可
```
    public function getFile() {
    $_SESSION['status'] = 0; //初始化进度
    session_write_close(); // 释放写锁
    for ($i=0; $i < 5; $i++) { // 模拟处理,sleep阻塞时间
        sleep(2);
        session_start();// 开启session
        $_SESSION['status'] = $i;
        session_write_close();// 释放写锁
    }
}
```

猜你喜欢

转载自blog.csdn.net/qq_32239417/article/details/89284594