谢邀
我通过代码来对你讲解吧。
echo date(‘Y-m-d H:i:s‘, time());
echo "
";
sleep(30);
echo date(‘Y-m-d H:i:s‘, time());
然后我打开两个页面,同时去请求我的脚本。
结果如下:
看到没?这两次请求都有对应的输出对吧(相当于向数据库里面插入信息)。
重点来了
我明明是同时请求浏览器的,为什么第二次请求被处理的时间是:
2018-03-31 01:07:35
好像是第一次请求被处理完之后结束的时间对吧。
为什么?因为我只开了一个PHP的worker进程:
这意味着什么呢?
因为第一次请求导致了worker进程被挂起了(因为sleep的原因,worker进程处于阻塞态)。所以,此时的worker进程不能去处理客户端的连接。因此,必须等到了第一次请求被处理完了,才可以处理第二次请求。于是第二次请求它被处理的时间是第一次请求被处理完的结束时间。
那么,既然worker进程阻塞了,为什么可以处理实际上在2018-03-31 01:07:05就发来的第二次请求呢(第二次请求和第一次请求是同时发起的)?原因是有Web服务,例如我这里的Nginx。它会去保持Nginx于客户端的连接。所以第二次请求可以推迟到2018-03-31 01:07:35再被处理。其实,如果你把我上面代码的sleep时间设置更久一点,例如:
sleep(60);
你会发现,第二次请求很可能会得到一个404状态。
好的,说了这么多,现在回到你的问题。
你是让用户x在1点的时候去请求PHP脚本。然后这时候调用了sleep方法对吧(sleep一分钟)。根据上面我的讲解,worker进程需要等到1点1分才可以去处理用户y实际在1点0分30秒的时候就发来的请求。然后,在1点1分的时候,worker因为sleep而在此被阻塞。直到1点2分才被唤醒,从阻塞态再到就绪态然后才处于可执行状态。然后才可以插入第二条数据。也就是说,到了1点2分的时候,数据库里面才会有第二条数据。
所以,在1点1分30秒的时候,数据库里面只有一条数据。
但是,我前面的结论都是在单个worker进程的基础上得到的。如果你的worker进程有多个,假设2个好吧。那么第一个worker进程因为第一次请求在1点钟被阻塞了(直到1点1分第1个worker进程才会被唤醒,然后插入数据)。OK,之后时间到了1点0分30秒,第二个请求发来了,因为第一个worker此时还是处于阻塞态,所以第二个worker进程会去处理这个请求。同样的,第二个worker进程在1点0分30秒被阻塞了(直到1点1分30秒第二个worker进程才会被唤醒,然后插入第二条数据)。因此,最终在1点1分30秒的时候,数据库里面是有两条数据的。
所以在1点1分30秒的时候,数据库里面有几条记录,看情况。
<<>>>