最近在ES5的标准库里遇到好几个问题。
一、write写入失败但是返回成功
检查多线程的时候,发现LOG里面打印次数有问题,仔细检查,发现前后的几句LOG只打印出来了前面的1句或2句,但是从后面的LOG来看,这段代码的流畅是没有问题。
write按照说明,原子操作,不缓存直接写入,返回写入长度,返回-1失败。所以在打印LOG的代码里并没有对文件加锁。
于是我写了个小程序,起来10个线程,同时写入一个文件,写了5分钟,结果发现,真正成功写入的不到1/10 ,如果失败,就是1W条左右写入不成功,但是写入失败的返回值既不是-1也不是0,都是成功。
看来只能给redhat包BUG了。
二、在多线程下调用curl下载
开启多线程使用curl的时候,出现curl的堆栈错误,查询了下,es5下是3.0的库,换成4.0的库后,继续堆栈错误,但是堆栈错误和以前不一样了。
自己写了个小程序,起了多个线程调用curl来下载,却一切正常。
于是把堆栈错误时的最后调用搜索了一下,发现果然也有人和我有一样的问题,下面的解答是curl在多线程先进行域名解析会出错。
我前面的测试程序用的全是IP,所有换了域名进行下载后果然出错。
把程序里所有的域名提前做了域名解析,然后再交给curl下载,一切正常。
三、curl的超时设置会取消进程设置的闹钟信号
这个是同事发现的,起了curl的下载后,定时器不运作了,一句一句注释,终于发现是curl的超时设置造成的了。
四、可怕的mysql_ping不退出
程序在运行过程中线程死锁,查看调用堆栈时发现,一个线程在调用mysql_ping无法退出,而这个检查是加了锁的,导致所有线程全部死锁。
至于为什么mysql_ping为什么退不出来,今天研究了一晚上,也没有发现原因。只是有一点,但就是network停掉后,mysql_ping肯定退不出来,至少我等了一个小时,程序也没有从mysql_ping退出来。但是在程序跑的过程中,网络是通的。
以后研究。
续:发现在多线程下,频繁的mysql_ping导致出错或者是mysql_ping不退出,改成mysql_query失败才mysql_ping,结果mysql_query反而出错导致程序退出了。真是够晕。
另:curl似乎在多线程还还是会有一定几率出错,设置CURLOPT_NOSIGNAL为1,情况就好的多了。