PHP写日志什么时候需要加锁?
先分析fwrite,直接找到PHP源代码:
static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
{vv
size_t didwrite = , towrite, justwrote; /* if we have a seekable stream we need to ensure that data is written at the
* current stream->position. This means invalidating the read buffer and then
* performing a low-level seek */
if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == && stream->readpos != stream->writepos) {
stream->readpos = stream->writepos = ; stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position TSRMLS_CC);
} while (count > ) {
towrite = count;
//chunk_size是8K
if (towrite > stream->chunk_size)
towrite = stream->chunk_size;
//分多次调用
justwrote = stream->ops->write(stream, buf, towrite TSRMLS_CC); /* convert justwrote to an integer, since normally it is unsigned */
if ((int)justwrote > ) {
buf += justwrote;
count -= justwrote;
didwrite += justwrote; /* Only screw with the buffer if we can seek, otherwise we lose data
* buffered from fifos and sockets */
if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == ) {
stream->position += justwrote;
}
} else {
break;
}
}
return didwrite; }
上图中红色注释是我加的。可以看出,fwrite会判断写入的内容长度,如果大于8K,会分多次write。每次write是直接调用了系统的write,这个是原子的。因为有多次write,就会有被中断的可能,就可能会出现错乱。
结论:写入小于8K,是原子性操作,不用加锁。反之需要。
error_log和file_put_contents函数
看这两个函数的源代码,发现最终也会调用_php_stream_write_buffer,所以结果是一样的。
程序验证:
先构造一个脚本,每次写10000字节(超过8K)
$a=str_repeat($argv[1],10000);
$i=0;
while($i++<10000)
file_put_contents('temp',$a."\n",FILE_APPEND);
用shell模拟并发
for((j=;j<;j++));do
php test.php a&
php test.php b&
done
结果可以明显看出来,出现了大量的错乱。
wc -l temp
temp
grep -P '(ab|ba)' temp|wc -l
如果把每次10000字节,改成8000如何呢,下面结果很明显了?
wc -l temp
temp
grep -P '(ab|ba)' temp|wc -l
TIP:怎么快速找到源代码呢?参考我的一篇博客中的方法:http://www.cnblogs.com/hxdoit/p/5193598.html
PHP写日志什么时候需要加锁?的更多相关文章
- .NET Core的日志[5]:利用TraceSource写日志
从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...
- [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件
本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...
- Spring 使用 SLF4J代替 Commons Logging 写日志 异常
项目的日志更换成slf4j和logback后,发现项目无法启动.错误提示 Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/ ...
- 程序员的修养 -- 如何写日志(logging)
在程序中写日志是一件非常重要,但是很容易被开发人员忽视的地方.写好程序的日志可以帮助我们大大减轻后期维护压力. 在实际的工作中,开发人员往往迫于的巨大时间压力,而写日志又是一个非常繁琐的事情,往往 ...
- winston写日志(译)
使用 有两种方式去使用winston,直接通过默认的logger,或者实例化自己的Logger,前者设计的目的是在你的应用程序中共享logger比较方便. 使用默认Logger 使用默认的logger ...
- ASP.NET Core 开发-Logging 使用NLog 写日志文件
ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...
- 2.2 代码块--delphi 写日志模块
//2.2 代码块--写日志 //调用例句如:LogMsg('FTP上传线程终止',False,true); procedure LogMsg(AMsg: string; const blnIsErr ...
- php大力力 [041节] 今天没有写日志哈
php大力力 [041节] 今天没有写日志哈 如何下拉,左边的side颜色 能顺延下去?? 今天做了一个表格显示
- 转:NLog 自定义日志内容,写日志到数据库;修改Nlog.config不起作用的原因
转:http://www.cnblogs.com/tider1999/p/4308440.html NLog的安装请百度,我安装的是3.2.NLog可以向文件,数据库,邮件等写日志,想了解请百度,这里 ...
随机推荐
- 数据结构-------单链表(C++)
相关信息: /** * @subject 数据结构 实验2 * @author 信管1142班 201411671210 赖俊杰 * @project 单链表 * @time 2015年10月29日1 ...
- HDU4521+线段树+dp
题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...
- linux下如何安装rzsz
1, 下载包: wget http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz 2, 解压缩:tar -zxvf rzsz-3.48.tar.gz ...
- DLX模板
对于数独问题 ; //3*3数独 ; // 一格能填9个数 9*9格 +; // 9*9*4=(9+9+9)*9+9*9 (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子 +MaxM ...
- HDU 5044 TREE
题意:一棵树上两种操作,操作1,改变u到v的每一点的值增加k,操作2,改变u到v每一条边值增加k.最后结束时问,每一点和每一条边的值. 初始时,点和边的值都为0. 分析: 很显然要用树链剖分,将点和边 ...
- Linux内核态抢占机制分析
http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html [摘要]本文首先介绍非抢占式内核(Non-Preemptive Kernel)和可抢占式内核( ...
- JavaScript实现命令行交互
原文地址: http://www.cnblogs.com/liaoyu/p/js-terminal.html 周末闲着想试试用 JavaScript 模拟命令行交互的功能,希望达到的几个功能点如下: ...
- 如何查看自己运行ubuntu是32位还是64位
当安装ubuntu在pc上,不推荐在32位pc安装64位操作系统,64位pc安装32位操作系统 方法/步骤 按ctrl+shift+t 快捷键,打开终端,输入sudo uname --m ,按下ent ...
- 被IDEA的打包功能打败了:dubbo服务端打包注意事项
下午在搭建一个基于dubbo和spring的服务端项目.结果打包成jar后各种报错. 起初是因为idea的机制,导致META-INF下自己的Mainfest.mf总是莫名被覆盖,于是报找不到主函数.后 ...
- 微支付开发(.net)
最近一周多进行微支付开发工作,总结一下关于微支付开发中遇到的问题. 如写得不对请大家提出,第一次自己写文章.嘿嘿... 1.申请微支付,登陆公众平台后(公众号为服务号并已认证),进入“服务”-“服务中 ...