先分析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写日志什么时候需要加锁?的更多相关文章

  1. .NET Core的日志[5]:利用TraceSource写日志

    从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...

  2. [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件

    本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...

  3. Spring 使用 SLF4J代替 Commons Logging 写日志 异常

    项目的日志更换成slf4j和logback后,发现项目无法启动.错误提示 Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/ ...

  4. 程序员的修养 -- 如何写日志(logging)

      在程序中写日志是一件非常重要,但是很容易被开发人员忽视的地方.写好程序的日志可以帮助我们大大减轻后期维护压力. 在实际的工作中,开发人员往往迫于的巨大时间压力,而写日志又是一个非常繁琐的事情,往往 ...

  5. winston写日志(译)

    使用 有两种方式去使用winston,直接通过默认的logger,或者实例化自己的Logger,前者设计的目的是在你的应用程序中共享logger比较方便. 使用默认Logger 使用默认的logger ...

  6. ASP.NET Core 开发-Logging 使用NLog 写日志文件

    ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...

  7. 2.2 代码块--delphi 写日志模块

    //2.2 代码块--写日志 //调用例句如:LogMsg('FTP上传线程终止',False,true); procedure LogMsg(AMsg: string; const blnIsErr ...

  8. php大力力 [041节] 今天没有写日志哈

    php大力力 [041节]  今天没有写日志哈  如何下拉,左边的side颜色  能顺延下去?? 今天做了一个表格显示

  9. 转:NLog 自定义日志内容,写日志到数据库;修改Nlog.config不起作用的原因

    转:http://www.cnblogs.com/tider1999/p/4308440.html NLog的安装请百度,我安装的是3.2.NLog可以向文件,数据库,邮件等写日志,想了解请百度,这里 ...

随机推荐

  1. pair work-Elevator Schedule附加题

    [电梯调度算法的实现和测试] [附加题] 首先,我要感谢周敏轩同学和薛亚杰,吴渊渊小组.UI的编写是在两个小组成员的共同努力下完成的,希望在第二次结对编程中能够再一起对UI界面进行更新和完善.UI编写 ...

  2. android 为activity添加optionMenu选项菜单

    <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android: ...

  3. Spring mvc 学习笔记

    记录下学习spring-mvc的技术要点,项目结构路径如下: 1. 首先要在web.xml中添加Servlet和filter的配置: <!-- 转码,防止乱码--> <filter& ...

  4. 在8086中,[ idata],[bx]表示内存单元时。可能是一个字节,也可能是一个字。

    可能表示一个字节,也可能表示一个字.主要由指令中另一个计算对象决定.如al表示一个字节.ax就表示一个字. 这个区别主要体现在循环中,偏移地址的循环变量是加1还是加2,al是偏移地址加1,ax是偏移地 ...

  5. 2013年最受欢迎的16个HTML5 WordPress主题

    本文中,我整理了16个最新.最受欢迎的WordPress主题,它们一致的特征是支持HTML5, 它们秉承最佳设计理念以及最新的流行趋势,将它们归纳与此,希望对喜欢HTML5,准备用WordPress做 ...

  6. ActionBar官方教程(5)ActionBar的分裂模式(底部tab样式),隐藏标题,隐藏图标

    Using split action bar Split action bar provides a separate bar at the bottom of the screen to displ ...

  7. 【HDOJ】1022 Train Problem I

    栈和队列训练题目. #include <stdio.h> #include <string.h> #define MAXNUM 1005 char in[MAXNUM]; ch ...

  8. 【原创翻译】Reducing Branch Delay to Zero in Pipelined Processors

    在流水线处理器中减少分支延迟到零 Antonio M. Gonzalez and Jose M. Llaberia 摘要 一种减少流水处理器中分支延迟到零的机制将在本文被描述以及评估.这种机制基于多重 ...

  9. How to: Define a Windows Communication Foundation Service Contract

    This is the first of six tasks required to create a basic Windows Communication Foundation (WCF) app ...

  10. Log4Net 配置和使用

    转:http://www.cnblogs.com/chencidi/archive/2010/01/12/1645291.html web.config配置如下: <?xml version=& ...