解忧杂货店


搬家之后,上下班花在地铁上的时间,单程就从10分钟大涨至45分钟,正好适合读书。三四天的时间,差不多正好每天一两个小节,一直想读而没时间读的《解忧杂货店》,就在哐啷哐啷的轨道声中读完了。

给shell脚本加锁


在内部测试服务器上,有一个shell脚本用于将csv数据表格转换成Python数据文件。在执行过程中的某一步,由于需要对一些文件进行写操作,所以如果同时有两个人运行了导表程序,则第二个人运行到此步骤时,就会失败并退出,这既拖慢了第一个人的导表速度,而且对第二人的体验也不好(运行了五分钟然后告诉我失败了?黑人问号……)。所以我就想给这个shell脚本加个锁,保证同一时刻只能有一个实例在运行,并及早给出其他用户提示信息。

如何估算一个Python对象的内存占用


需求

最近接到一个需求:制作一个工具,可以即时查看线上服务器的内存使用状况,不要求精确,但是如果存在爆内存的情况,要能查到有嫌疑的Entity是哪个。

pytracemalloc神器无用武之地

在网上一番搜索,对GuppyPySizerpytracemalloc进行比较之后,貌似大家对pytracemalloc的评价较好。按照官方文档,需要对Python2.7.8源码打个patch,虽然我们项目使用的是2.7.11,不过也问题不大,打Patch时obmalloc.c里面有2个reject,手动将其merge到源码中即可。编译通过,写个小程序进行实现,可行,而且可以定位到源代码的行号,确实神器。于是将情况报告给领导,正以为将大功告成之时,领导说,tracemalloc这个库我们已经集成到引擎中,但是对服务器性能有影响,所以一般就在测试环境用用,不满足即时查看线上服务器内存使用状况的要求。根据我了解的情况,确实有这样的问题,pytracemalloc其实是修改了Python虚拟机分配内存时的代码,所以:

踩坑记——覆写Python中的__cmp__


最近做一个简单的排行榜功能时,不小心踩到一个Python语言上的坑,花费掉我不少时间才找出具体原因,值得记录一下。


具体功能需求是这样的,制作一个500人的积分排行榜(TOP 500),每个人的积分只增不减,分数相同时比较上榜的时间戳,先达到积分的用户排名靠前。

这种排行榜之前已经做过无数个,一般的,会先抽象出一个TopItem对象,保存用户的积分,以及姓名、UUID等相关信息。然后用一个list对象tops保存有序的500元素,并用一个dict对象cache保存一个uuid到TopItem的映射。由于Python对象的引用特性,多增加一个dict对象,并没有增加TopItem对象的副本,而是均指向同一个TopItem对象,所以内存方面也不会有什么太大的问题。

2017年上半年书单


非技术类

  • 长恨歌 王安忆
    • 一部上海百年画卷,从细节纹理描绘城市的巨变。王琦瑶的一生,和我们大多数人一样,有高光,但大部分时间是平淡和挣扎,个人的努力最终还是要屈服于历史的进程O-O

日本之行感悟


上周参加公司的旅行福利,去了一趟日本,主要行程是大阪-奈良-京都-东京。这是我第二次去日本了,上一次是去参加Tokyo Game Show(TGS),主要是在东京都内,而且自己活动的时间比较少。这次纯粹是旅行,看的更多,体会也更深一些。

探索skynet(四):服务之间的通信


《探索skynet(三):消息队列》中已经提到,skynet中每个服务都有自己的地址和消息队列。有了这个基础,理解服务之间的消息通信,就比较简单了。

skynet.call

以最常用到的skynet.call为例,它通过调用skynet.core.send(也即,lua-skynet.c中的lsend函数)–> skynet_send函数 –> skynet_context_push函数,向目标服务的消息队列中插入了一条消息。

Python内存管理模块的一个奇技淫巧


最近在读Python源码中有关内存管理的部分。Python在分配小块内存(小于256字节)时,采用了内存池,以降低对内核内存分配程序的调用频次。在内存池的设计上,采用了一个分层的设计,由上到下依次是arena、pool、block。这次我看到的这个比较费解的结构,就来自于分配内存时,对于pool的处理。

高房价在扼杀什么


这个周末,看到水木上一篇文章《被疏解了》,大意就是说一个三北博士(本科、硕士、博士都是北大的),毕业后进入中科院北京某研究所工作三年,还是由于房价太高以及子女教育问题,选择去南京了。

每隔一段时间,就会有这样的一篇热文,来控诉帝都的房价。本来我都习以为常了——一时逃离北上广,一时又逃回北上广,循环往复——但是正好最近目前住的小区里也发生了一件相关的小事,让我又有了一些新的感慨。

探索skynet(三):消息队列


skynet框架底层使用消息队列作为各个服务之间通信的工具,之前在探索skynet如何启动一个服务时也提到了创建skynet_context时会初始化一个队列,并且也笼统的提到了如何为一个服务设置callback。那么接下来就详细的看看,skynet里有关消息队列的部分是如何设计和实现的。

基础结构

skynet中有关消息队列的实现主要放在skynet_mq.c中。

skynet_mq.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct message_queue {
struct spinlock lock;
uint32_t handle;
int cap;
int head;
int tail;
int release;
int in_global;
int overload;
int overload_threshold;
struct skynet_message *queue;
struct message_queue *next;
};

struct global_queue {
struct message_queue *head;
struct message_queue *tail;
struct spinlock lock;
};