html5中文学习网

您的位置: 首页 > 网络编程 > PHP编程 » 正文

linux下创建线程内存泄漏,php的json_encode等_PHP教程_编程技术

[ ] 已经帮助:人解决问题

 6c6HTML5中文学习网 - HTML5先行者学习网

这次还是把遇到的几个问题整理一下,希望再遇到的同学能轻松解决。另外最近博客的feeds延迟更新的原因也会一起说明一下。6c6HTML5中文学习网 - HTML5先行者学习网

1.linux下创建线程导致内存泄漏
今天在外网发布了一个server之后,用top发现virt的使用量一直在涨,而且一次涨8m。于是可以断定有内存泄漏了,经过排查,最终确定原因出在多线程的问题上:
代码如下:6c6HTML5中文学习网 - HTML5先行者学习网

					123456
					pthread_t thread_id;int ret=pthread_create(&thread_id, NULL, flush_thread_work, (void*)&m_sql_client);if(ret!=0){    APPSCORE_ERROR("Thread creation failed:%d",ret);    return ret;}

在flush_thread_work函数内部:6c6HTML5中文学习网 - HTML5先行者学习网

					12345
					void* flush_thread_work(void* args){    //....do something    return NULL;}

代码中启动了一个线程之后,主进程就继续执行,任由新线程自生自灭了(没有调用thread_join),而主进程每隔一段时间就会拉起这样一个线程来做一些数据落地的事情。6c6HTML5中文学习网 - HTML5先行者学习网

这样的写法实际上是会造成内存泄漏的.
Linux man page 里有已经说明了这个问题:6c6HTML5中文学习网 - HTML5先行者学习网

When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore, pthread_join must be called once for each joinable thread created to avoid memory leaks.6c6HTML5中文学习网 - HTML5先行者学习网

也就说线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!6c6HTML5中文学习网 - HTML5先行者学习网

解决方法有两种:
a.在线程执行的函数内手工释放6c6HTML5中文学习网 - HTML5先行者学习网

					123456
					void* flush_thread_work(void* args){    //....do something    pthread_detach(pthread_self());    return NULL;}

b.在线程启动时,设置线程的PTHREAD_CREATE_DETACHED属性6c6HTML5中文学习网 - HTML5先行者学习网

					1234567891011121314
					pthread_attr_t attr;pthread_attr_init (&attr);pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); int ret=pthread_create(&thread_id, &attr, flush_thread_work, (void*)&m_sql_client);if(ret!=0){    //记住attr也要析构,否则又是一个内存泄漏    pthread_attr_destroy (&attr);    APPSCORE_ERROR("Thread creation failed:%d",ret);    return ret;}  //记住attr也要析构,否则又是一个内存泄漏pthread_attr_destroy (&attr);

这样问题就可以解决了。
参考资料:
解决了一个隐蔽的内存泄漏——pthread_create后没有detach导致内存持续增长6c6HTML5中文学习网 - HTML5先行者学习网

2.php的json_encode函数问题
在公司做了一个应用,是php与c++进行网络交互,所以选择了json这种比较通用的序列化格式,然而却遇到了比较奇怪的问题。
先来看如下代码(php):6c6HTML5中文学习网 - HTML5先行者学习网

					12345
					$objs = array();$objs[1] = 'a';$objs[2] = 'b';$objs[4] = 'd';echo json_encode($objs)."/n";

输出的结果如下:6c6HTML5中文学习网 - HTML5先行者学习网

		{"0":"a","1":"b","3":"d"}

这样是正常的,用jsoncpp也可以正确的解析出来,php自动将$objs当作一个关联数组来生成json数据了。
然而当把代码换成如下:6c6HTML5中文学习网 - HTML5先行者学习网

					123456
					$objs = array();$objs[0] = 'a';$objs[1] = 'b';$objs[2] = 'c';$objs[3] = 'd';echo json_encode($objs)."/n";

则输出结果如下:6c6HTML5中文学习网 - HTML5先行者学习网

		["a","b","c","d"]

jsoncpp按照之前的解析方法是解析不出来的~
其实对php来说,这也是合理的,问题在于在php里面普通数组和关联数组都是array,而对c++来说,却存在vector和map之分,所以如果还是想要json_encode生成关联数组的格式,那么需要这样写:6c6HTML5中文学习网 - HTML5先行者学习网

					123456
					$objs = array();$objs[0] = 'a';$objs[1] = 'b';$objs[2] = 'c';$objs[3] = 'd';echo json_encode((object)$objs)."/n";

结果如下:6c6HTML5中文学习网 - HTML5先行者学习网

		{"0":"a","1":"b","2":"c","3":"d"}

3.本博feed延迟不更新的原因
之前由于对feedsky的feed更新十分不满,所以参考网上的做法,建立了一个feed.vimer.cn,而本博所在的域名空间会自动根据域名创建一个子目录 - feed,修改这个目录下的.htaccess文件如下:6c6HTML5中文学习网 - HTML5先行者学习网

					12345
					<IfModule mod_rewrite.c>RewriteEngine OnRewriteBase /RewriteRule . http://feed.feedsky.com/vimer [L]</IfModule>

那么当访问 feed.vimer.cn 时,会自动跳转到 http://feed.feedsky.com/vimer。
然而我忽略了一个问题,那就是wordpress默认的feed链接是 http://vimer.cn/feed/rss2,而/feed/rss2会被解析成子目录,从而自动跳转到 http://feed.feedsky.com/vimer ,所以feedsky就会不停的读 http://feed.feedsky.com/vimer 这个链接的feed,当然不会有任何新数据。。6c6HTML5中文学习网 - HTML5先行者学习网

所以最后还是把这种方式废弃掉了,看来真是冤枉了feedsky呀~~~6c6HTML5中文学习网 - HTML5先行者学习网

OK,最近的总结就这么多~6c6HTML5中文学习网 - HTML5先行者学习网

6c6HTML5中文学习网 - HTML5先行者学习网
6c6HTML5中文学习网 - HTML5先行者学习网
(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助