'民工技术' Category

  • 最简单方法远程调试Python多进程子程序

    March 5, 2010

    Python 2.6新增的multiprocessing,即多进程,给子进程代码调试有点困难,比如python自带的pdb如果直接在子进程代码里面启动会抛出一堆异常,原因是子进程的stdin/out/err等文件都已关闭,pdb无法调用。据闻winpdb、Wing IDE的调试器能够支持这样的远程调试,但似乎过于重量级(好吧前者比后者要轻多了,但一样要wxPython的环境,再说pdb的灵活可靠它们难以比拟)。 其实只需稍作改动即可用pdb继续调试子进程的代码,思路来自这个博客:子进程的stdin/out/err关闭了,那可以自己重新按/dev/stdout的名称打开来用。当然这指*nix下,win下要麻烦一些,后面再说。 pdb支持自定义输出输入的文件,我再稍作改动,使用fifo管道(Named Pipe)来完成pdb的输出输入的重定向,这样的好处是,可以同时对父子进程调试! multiproces_debug.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #!/usr/bin/python   import multiprocessing import pdb   def child_process(): print "Child-Process" pdb.Pdb(stdin=open('p_in', 'r+'), stdout=open('p_out', 'w+')).set_trace() var = "debug me!"   def main_process(): print "Parent-Process" p = multiprocessing.Process(target = [...]

  • Python, C-Python, Cython代码与GIL的交互

    January 7, 2010

    这篇笔记相对Python来说,有点底层,先来解释几个名词: C-Python: 或者CPython,指C实现的Python虚拟机的基础API。最通用的Python就是是基于C实现的,它的底层API称为C-Python API,所有Python代码的最终变成这些API以及数据结构的调用,才有了Python世界的精彩; Cython:准确说Cython是单独的一门语言,专门用来写在Python里面import用的扩展库。实际上Cython的语法基本上跟Python一致,而Cython有专门的“编译器”先将Cython代码转变成C(自动加入了一大堆的C-Python API),然后使用C编译器编译出最终的Python可调用的模块。 GIL:Global Interpreter Lock,是Python虚拟机的多线程机制的核心机制,翻译为:全局解释器锁。其实Python线程是操作系统级别的线程,在不同平台有不同的底层实现(如win下就用win32_thread, posix下就用pthread等),Python解释器为了使所有对象的操作是线程安全的,使用了一个全局锁(GIL)来同步所有的线程,所以造成“一个时刻只有一个Python线程运行”的伪线程假象。GIL是个颗粒度很大的锁,它的实现跟性能问题多年来也引起过争议,但到今天它还是经受起了考验,即使它让Python在多核平台下CPU得不到最大发挥。 GIL的作用很简单,任何一个线程除非获得锁,否则都在睡眠,而如果获得锁的线程一刻不释放锁,别的线程就永远睡眠下去。对于纯Python线程,这个问题不大,Python代码会通过解释器实时转换成微指令,而解释器给他们算着,每个线程执行了一定的指令数后就要把机会让给别的线程。这个过程中操作系统的调度作用比较微妙,不管操作系统怎么调度,即使把有锁线程挂起到后台,尝试唤醒没锁的,解释器也不给他任何执行机会,所以Python对象很安全。 所以一般来说,做纯Python的编程不需要考虑到GIL,它们是不同层面的东西,但是模块级别的C-Python、Cython等C层面的代码,跟Python虚拟机是平起平坐的,所以GIL很可能需要考虑,特别那些代码涉及IO阻塞、长时间运算、休眠等情况的时候(否则整个Python都在等这个耗时操作的返回,因为他们没获得锁,急也没办法)。 想体现这个过程,很简单,考虑下面的代码,一段纯Python和一段纯C的循环,每次print一段文字就睡眠一秒。 1 2 3 4 5 6 7 void _c_loop ( void ) { while(1) { printf("Print from C loop\n"); sleep(1); } } 1 2 3 4 def _py_loop(): while True: print "Print from Python loop" time.sleep(1) 先不管他们是如何揉合到同一Python进程里面,两个进程分别执行了这两个函数后,他们应该以大概相互间隔着输出文字;但实际情况是,Print from Python loop这句出现了一次之后(先启动了纯Python线程,否则它连启动的机会都没),剩下的输出全都是Print from C [...]

  • Ubuntu 下使用蓝牙/USB连接黑莓8700上网

    December 18, 2009

    黑莓8700支持EDGE网络,用来做GPRS Modem是相当理想的,标准的mini usb接口,蓝牙2.0,完全足够EDGE的网络速度; 本来以为用蓝牙连接会很简单,在blueman里面连接即可,可是实际上,不行: Failed: Modem Manager did not support the connection 之前用blueman连接Nokia的机,是没问题的,看来黑莓的Modem协议有点不同……Google了一下,找到了不少BB在Linux下的资料:How use BlackBerry device with Linux【介绍了Linux对黑莓的配置、同步、安装软件、Modem、Java开发】how to teather blackberry and linux via bluetooth【连BB蓝牙的完整过程,试验不成功】Berry4all 通过USB连接BB Modem的专用程序 测试Berry4all终于能够连接上BB的GPRS,观察Berry4all其实也是建立了串口通信后,使用pppd的协议来建立数据链接的,要连接cmnet,还得修改其conf下的att-chat,即其中的“拨号”协议; blueman虽然不能建立Modem链接,但是还是能够建立起/dev/rfcomm0,即通过蓝牙的串口链接;使用蓝牙教程,基本上都是使用hcitool等工具来配置的,使用起来真的好不方便,而blueman不是刚好帮忙搞定了蓝牙的配对连接等麻烦事情么…… 于是把Berry4all的conf目录的att跟att-chat文件复制到/etc/ppp/peers,参照别的教程的配置,修改att,在开始115200那行前,加入nodetach跟/dev/rfcomm0两行,最后的connect调用chat文件的路径改成connect "/usr/sbin/chat -f /etc/ppp/peers/att-chat",att-chat里面修改一行:OK 'AT+CGDCONT=1,"IP","cmnet"' ,最后运行sudo pppd call att,终于用蓝牙连上了GPRS; 其实使用ppp连接modem的方法是最传统的,也是高度可定制(如连接后配置路由表、IP、DNS),不管是用Cable、USB、蓝牙还是红外,都可以这样完成,Of Linux, GPRS Phones, Serial Cable, Irda, Bluetooth and USB文章里面列举了好多这些例子;我修改了其中的三个脚本:gprs, gprs-connect-chat, gprs-disconnect-chat替代了上面Berry4all的att脚本,因为这脚本里面的注释非常详细,以防以后需要的调整; 这是我打包了修改好后(适用于移动CMNET上网的)gprs脚本,使用blueman连接了rfcomm0后,运行sudo pppd call gprs,就能连接上GPRS,ifconfig查看出现一个ppp0,可以直接上网了; 如果不使用blueman,完全使用bluez的工具的话,可以参照Blackberry [...]

  • ffmpeg API 笔记:使用libavcodec/libavformat/libswscale

    December 11, 2009

    Update 2010.1.5: 其实研究ffmpeg不用找什么教程,第一步应该是下载ffmpeg的源码包。下面提到的An FFmpeg and SDL Tutorial确实有讲解,但是教程总是跟不上代码的变化的,所以直接看可工作代码最好;ffmpeg的结构很分明,后台是几个库:libxxx,前台是三个程序ffmpeg, ffplay, ffserver,那篇教程说的就是ffplay的实现。一个播放器,其实重点不是解码,解码的东西是lib去做的,主要是做声音视频的时钟同步。ffplay的代码可以说是一个可用播放器最简单的实现了,源码里面有个output_example.c,可以说是最基本的api示范吧。ffmpeg是转换编码解码转换程序,因为涉及重新采样等等,所以代码量也不少的。 这两天"调研"了下ffmpeg的API,不得不承认被雷倒:ffmpeg又是一个很geek的项目,纯社区开发,基于逆向,功能强大,但是文档极度有限,想了解API?看源码去…… 网上关于ffmpeg API的资料,无非是ffmpeg文档里面的两个链接,Using libavformat and libavcodec byMartin Böhme(以及其Update,介绍了新引入的API)跟An FFmpeg and SDL Tutorialby Stephen Dranger;两个tutorial基于ffmpeg 0.4.8,现在ffmpeg发布的版本是0.5.0,好像数值相差不大,不过0.4.8是5年前的了(相比之下wine用了15年版本号才到达1.0,有过之余无不及),两个教程里面的代码在0.5.0下一编译,哇,一堆错误,可不仅有些api函数变了,有些结构成员压根就没了,头文件的位置更是不一样(各个库分家了)……所以我调试了好几个小时,终于把例子的代码弄好(其实Martin Böhme那篇有一段09年加入的更新说明,链接了有相关的解决办法,我一开始没注意,几个小时自己解决,不过也有收获)。 最后我调试好的代码流程:打开一个视频文件,抓取前5帧保存为文件;【基于Stephen Dranger的Tutorial1】源码在此:GoogleCode av_register_all();//初始化ffmpeg库,如果系统里面的ffmpeg没配置好这里会出错 av_open_input_file(); av_find_stream_info();//查找文件的流信息 dump_format();//dump只是个调试函数,输出文件的音、视频流的基本信息了,帧率、分辨率、音频采样等等 for(...);//遍历文件的各个流,找到第一个视频流,并记录该流的编码信息 sws_getContext();//根据编码信息设置渲染格式 avcodec_find_decoder();//在库里面查找支持该格式的解码器 avcodec_open();//打开解码器 pFrame=avcodec_alloc_frame();//分配一个帧指针,指向解码后的原始帧 pFrameRGB=avcodec_alloc_frame();//分配一个帧指针,指向存放转换成RGB后的帧 avpicture_fill(pFrameRGB);//给pFrameRGB帧加上分配的内存; while true{ av_read_frame();//读取一个帧(到最后帧则break) avcodec_decode_video();//解码该帧 sws_scale();//把该帧转换(渲染)成RGB SaveFrame();//对前5帧保存成ppm图形文件(这个是自定义函数,非API) av_free_packet();//释放本次读取的帧内存 } avcodec_close(); av_close_input_file(); 用到的API就这么多,当然实际代码稍复杂一点;ppm图像是类似BMP的非压缩格式,SaveFrame就是相当于把pFrameRGB的内存拷贝进文件,写文件并不复杂; 调试过程的问题,首先是头文件,ffmpeg 0.5.0的API已经拆分成好几个独立的库,用pacman -Ql ffmpeg看了下文件分布,在include下好几个目录都是它的,看名字可以大概猜出他们的功能: libavcodec:CODEC其实是Coder/Decoder的缩写,也就是编码解码器;libavdevice:对输出输入设备的支持;libavformat:对音频视频格式的解析libavutil:集项工具;libpostproc:后期效果处理;libswscale:视频场景比例缩放、色彩映射转换; 修改好头文件包含,终于少了些not [...]

  • Google Code项目Wiki页在SVN仓库被复位后无法修改的Bug

    October 27, 2009

    update:2010.1.25这个问题的状态终于被改成Fixed。 Google Code的项目控制因为其简洁深受很多开源作者的喜欢,PT好几个项目都是存放在Google Code上,不过之前遇到了一个些少恼人的Bug: 当建立了Wiki页,因为某种原因重置了SVN仓库,那原来的Wiki页将无法修改、无法删除(返回500 Server Error)。 重置SVN一般属于特殊情况,比如要把另外一个服务器的SVN仓库搬到另外一个SVN,而只保留后来的版本数据,才需要重置SVN仓库。我当时的情况是,不小心把包含自己帐号密码的测试脚本提交了上去SVN;版本管理的特点是版本修改是无法被抹除的,情急之下只好放弃版本痕迹,备份了文件,请求了SVN重置;之后就发现原先的Wiki页无法修改了。 一番查找后,发现Google Code自身的Support里面早有人发现了这个问题,可以看到,这个Bug第一次在2007年11月就有人提出了,一直到现在都陆续有人确认Bug依然存在……所以当时我就没管那个有问题的Ghost Page了,任其放着;两年都没有修复的bug看了没什么好指望的了; 不过最近这个问题有人提出了个颇为纠结的解决办法:创建wiki/the_page文件(跟之前的wikipage同名),然后不断修改递交svn,当svn的revision版本号高于重置之前wiki page最后修改的版本号,就可以修改或者删除这个Ghost Page了…… 想到我那个项目现在的版本号早就超过了之前重置SVN仓库时候的版本号,直接跑去wikipage点Delete this page,哈,直接搞定了! 从这个Bug可以透视到Google Code的Wiki页构建机制:Wiki页跟SVN仓库内相应文件是紧密互动的,在Web对Wiki页的修改就相对于直接提交了相应SVN内的文件,当直接修改SVN内的Wiki文件时候,Web上的Page自动根据SVN刷新WEB页的缓冲,并记录文件的修改版本号;而重置了SVN仓库将导致SVN的版本号从0重新开始,这样Wiki页的缓冲模块没法找到相应的版本号对应的wiki文件进行操作,所以报告500错误;只能当版本号重新达到原先的最后修改时,Wiki Web才能正常的和SVN交互。 另外有趣的是,Google的程序员似乎对修复这个Bug没什么兴趣;可能容易引起新的bug吧,呵呵。

  • 锐捷/联想/神州数码 802.1x客户端支持MacOS、BSD

    October 9, 2009

    Insion同学之前发来一段可以在MacOS/BSD编译运行获取网卡MAC地址的代码,于是整理了一下,让几个802.1x Client都能支持MacOS/BSD了。 下载了个FreeBSD 7.2在vbox虚拟机里面装了下,发现FreeBSD比Linux好像原始多了[呃,我说安装程序],分区的时候他不叫Create Partition,叫Create Slice,我对着界面看了半天才猜到,囧;退出那里写着:Q = Finish,Quit就Quit嘛,什么Finish,纠结……但还好,其他的配置跟Linux还是很相像的,调试了一下就有了全可编译的代码了。 代码部分修改倒没多少,就添加了一个专门给BSD系系统获取MAC的函数,再用maroc判断一下,以及几个头文件,就完事了,有点麻烦的是makefile,发现freebsd默认那个make好像是很古老很古老的版本,我程序里面那个Makefile是用了vim里面c-support插件里面带的Makefile模板,有点复杂,但是freebsd居然不支持!所以整理了个简单的版本,专门给MacOS/BSD编译,也方便别人的修改;另外一个原因是,程序里面转换服务器消息时候用了iconv库,linux里面iconv是系统内嵌库来的,用不着链接的时候给出参数,但MacOS/BSD偏偏就要-liconv…… 需要编译MacOS/BSD版本的同学,可以check出项目里面trunk的代码,运行make -f Makefile.bsd来编译。Insion同学已经编译成功,而且在他的主页上有二进制版下载了。 相对的说,可能在MacOS里面编译是最麻烦的,我大概说说流程(实际上我没试过,我可没Mac机器[T.T]) 1.安装gcc,参考这里从http://connect.apple.com/的Dev Tools里面下载Xcode Tools,安装。2.编译安装libpcap,从http://www.tcpdump.org/release/libpcap-1.0.0.tar.gz下载源码,tar xvfz libpcap-1.0.0.tar.gz解压,进去该目录,./configure、make、make install安装完成;3.编译802.1x客户端,从所用项目内签出源码,在目录内make,没出什么差错的话,已经完成了。然后按Readme.txt的方法安装运行,即可! 项目主页 锐捷:http://code.google.com/p/zruijie4gzhu/联想:http://code.google.com/p/zlevoclient/神州数码:http://code.google.com/p/zdcclient/

  • 油猴脚本Twitter Picture Preview支持中文推特圈、官方Twitter

    October 8, 2009

    油猴脚本:Twitter Picture Preview Feature: Adding preview thumbs right after a short url to an popular image-service site in twitter.功能:给twitter内包含指向图片服务的网址加上该图片的缩略图。 客户端支持/Client Supports:twitter.com / itweet.net / twitese.appspot.com 图片服务支持/Image-Service Supports:twitpic / flic.kr / moby.to / yfrog / ts1.in / hellotxt.com / twitxr.com / twitgoo.com 维护了一下之前写的油猴脚本:Twitpic in itweet,从另外一个相同功能的脚本TwitterPhotoShow的代码,通过监控items容器的DOM的事件DOMNodeInserted、DOMSubtreeModified来相应内容的变化,这样就可以把原来的定时器什么一大堆的代码去掉了; 同时利用了一下javascript的对象特性,原先的代码可能看起来还跟C类似的,重写一下语法看起来好像差很远了……改写的好处是添加新的图片服务处理就容易多了。比如一个处理器是这么写的: 1 2 3 4 5 6 7 img_processor['ts1in'] = { [...]

  • Acer Aspire 4736ZG 本本上安家Linux的小问题

    September 27, 2009

    早天在新蛋上入手了Acer Aspire 4736ZG本本一台,T4200、1G、NV105M、250G,带蓝牙摄像头等,3600,还送了一台水星无线路由。低端本本为了降低成本,很多都是不装Windows的,这款也是,本来以为原装系统都是Linux,应该对Linux兼容不错的啦,那天到提货点验本本时候,运行一看,傻了,那个什么Linpus,2.6.15的内核,没带X,lshw没有,lspci没有,hwinfo更没有,总之就没什么东西好看的,除了黑漆漆的画面告诉我屏幕没坏点,就匆匆打上包回来了。 第一件事就是用Arch 09.08的Live CD启动重新分区,顺便装好core,但是启动后又傻了,连不上有线网卡……这款机器的网卡是Atheros AR8132的千兆卡,不知道是太新还是太罕见。几经折腾后发现规律:完全关机重开后,Arch就能认到网卡,ipconfig -a能看到eth0,但是ifconfig eth0 up了之后,是这个样子的: eth0 Link encap:Ethernet HWaddr 00:26:18:80:C5:AB UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4294967293 errors:4294967278 dropped:4294967290 overruns:4294967293 frame:4294967281 TX packets:4294967293 errors:4294967284 dropped:0 overruns:4294967293 carrier:4294967291 collisions:4294967281 txqueuelen:1000 RX bytes:4294967293 (4095.9 Mb) TX bytes:4294967293 (4095.9 Mb) Interrupt:28 大堆奇怪的数字,这时候不管dhcp还是手动指定IP,都没法正常工作的,如果这时重启,好,完全认不了网卡了,又要完全关机再开一次。 这个问题在Arch论坛上面也有人碰到,他的是华硕eeePC 1005HA,也是上个月的帖子。[详细情况帖子里面比较完备,但是,未解决] 于是我就转战Ubuntu。Ubuntu 9.04的Live CD版本也是没能驱动好这块网卡的,但是这里找到解决方法,总之就是到Atheros官网下载网卡的驱动,编译,挂载驱动模块,幸好Ubuntu的Live CD跟初始系统都带了GCC和Make utils,编译安装过程倒没什么波折,很快就折腾好连上网了。呃,怎么这么简单?于是试试在台式机的Arch上面编译了这个atl1c.ko,哇,一开始就一屏幕的错误……后来发现这个是这个驱动跟内核兼容问题,Ubuntu好像专门有补丁搞定的,Ubuntu 9.04把内核升级到2.6.28.15-generic网卡就完全正常了,也顺便下载了9.10的Live CD,直接iso启动,发现虽然是31内核,但是网卡工作也正常……好吧……看来要么等kernel彻底搞定这块网卡的驱动,不然只能自己找Ubuntu的patch来编译才能跑Arch了…… Ubuntu很是省心,挂上受限驱动什么3D特效全都出来了,跑了下glxgears,大概2600fps,比台式机的集显好一点吧……7025只有1300左右的fps;更新了一下系统,用Ubuntu [...]

Page optimized by WP Minify WordPress Plugin

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org