热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHPsession并发及session读写锁分析-PHP源码

关于PHPsession并发及session读写锁问题估计各大程序员都不会想到这个问题,因为一般情况我们不会使用session来做并发操作了,但有时也有可能用到,下面整理一个session并发及session读写锁文章供各位参考。
关于PHP session并发及session读写锁问题估计各大程序员都不会想到这个问题,因为一般情况我们不会使用session来做并发操作了,但有时也有可能用到,下面整理一个session并发及session读写锁文章供各位参考。

PHP这门程序设计语言简单得令人发指,那是因为PHP的作者们太神通。今天我来谈谈所有的phper都熟悉的session(会话)。

需要说明的是:

1.示例代码中分别以files,redis储存会话数据

2./session/setUserFile和/session/setUserRedis设置user_name,user_id两个key,并sleep了3s

3./session/setLoginFile和/session/setLoginRedis设置last_time一个key

4./session/indexFile和/session/indexRedis模板中两个ajax请求,/session/setUserFile和/session/setUserRedis立即执行,/session/setLoginFile和/session/setLoginRedis延迟300ms,是为了模拟同一个用户,同时在两个页面(请求)修改会话数据

执行结果表象:

请求:/session/indexfile

第一次访问:

PHP session并发及session读写锁分析

第二次访问:

PHP session并发及session读写锁分析

请求:/session/getsessionfile

array(3) { ["user_name"]=> string(10) "xudianyang" ["user_id"]=> string(3) "123" ["last_time"]=> int(1419411695) }

以文件保存会话数据结论:/session/setUserFile执行时间为3.1s,/session/setLoginFile执行时间为2.81s(如果加上ajax延迟刚好两个请求的响应时间都是3.1s)

请求:/session/indexredis

第一次访问:

PHP session并发及session读写锁分析

第二次访问:

PHP session并发及session读写锁分析

请求:/session/getsessionredis

array(2) { ["user_name"]=> string(10) "xudianyang" ["user_id"]=> string(3) "123" }

为什么?

手册中有这样的描述:

void session_write_close ( void )

End the current session and store session data.

Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.

也就是说session是有锁的,为防止并发的写会话数据。php自带的的文件保存会话数据是加了一个互斥锁(session_start()的时候),从而解释了上面呈现的两个请求响应时间相同。但是以redis保存会话数据时,第二个ajax虽然没有阻塞,但是会话数据并没有写入到redis,那我们追溯一下源码就有答案了。

php-5.4.14源码

默认的files的save_handler

php-5.4.14/ext/session/mod_files.c

PHP session并发及session读写锁分析

redis的save_handler

phpredis中的redis_session.c中并无实现session读写锁的机制,那上述如何解释呢?其实如果我们将session的源码大致浏览一下,就可以解释了。因为会话在session_start之后,将会话数据就会读取到$_SESSION(在扩展内部全局变量PS(http_session_vars))中,在PHP_RSHUTDOWN_FUNCTION(session)(请求释放)时,通过php_session_flush(TSRMLS_C)将会话数据写入储存介质,也就是说会话的数据并不是实时写入到储存介质的。

这就解释了,为什么redis保存会话数据时,/session/setLoginRedis看似未将last_time写入到redis,实质是写了,但是当/session/setUserRedis请求释放时(由于最开始会话数据中并无last_time这个key),要将所有的会话数据写入到储存介质,从而覆盖了/session/setLoginRedis请求写的值,到此解释了上述的问题。

测试代码:

Session.php

代码如下
set('user_name', 'xudianyang');
        $session->set('user_id', '123');

        sleep(3);
        echo json_encode($_SESSION);
        return false;
    }

    public function setLoginRedisAction()
    {
        $session = CoreFactory::session();
        $session->set('last_time', time());

        echo json_encode($_SESSION);
        return false;
    }

    public function indexRedisAction()
    {
        // Auto Rend View
    }

    public function getSessionRedisAction()
    {
        $session = CoreFactory::session();
        var_dump($_SESSION);

        return false;
    }
}

indexfile.phtml



  
  
  
  


同时发起2两个ajax请求

indexredis.phtml



  
  
  
  


同时发起2两个ajax请求


推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 本文介绍了DataTables插件的官方网站以及其基本特点和使用方法,包括分页处理、数据过滤、数据排序、数据类型检测、列宽度自动适应、CSS定制样式、隐藏列等功能。同时还介绍了其易用性、可扩展性和灵活性,以及国际化和动态创建表格的功能。此外,还提供了参数初始化和延迟加载的示例代码。 ... [详细]
  • Allegro总结:1.防焊层(SolderMask):又称绿油层,PCB非布线层,用于制成丝网印板,将不需要焊接的地方涂上防焊剂.在防焊层上预留的焊盘大小要比实际的焊盘大一些,其差值一般 ... [详细]
  • 前言:关于跨域CORS1.没有跨域时,ajax默认是带cookie的2.跨域时,两种解决方案:1)服务器端在filter中配置详情:http:blog.csdn.netwzl002 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了一种处理AJAX操作授权过期的全局方式,以解决Asp.net MVC中Session过期异常的问题。同时还介绍了基于WebImage的图片上传工具类。详细内容请参考链接:https://www.cnblogs.com/starluck/p/8284949.html ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • 我将SpringMVC升级到Spring3.2.5.我的一些剩余调用即使存在,也会返回无法识别的字段异常.这是错误.Resolvingexceptionfrom ... [详细]
  • 缓存 分布式锁 Redis
    分布式锁现在Redis基本上没家公司都在使用,只是各自使用的场景不以,但Redis最出名的还是做为缓存服务器,提搞服务器的的吞吐量,下面我们来围绕这个作为缓存做一个总结今天的目标其 ... [详细]
author-avatar
mobiledu2502852147
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有