2016年5月18日星期三

在Windows下进行并行?批量同时启动限定数量的不同参数的多python实例的方法。(How to start a limit number of program (python instances with different argv) at the same time)

标题很长,但是也不一定说清楚我要做的事。下面我举一个例子。

我的实验程序接受3个参数argv1,argv2,argv3作为输入,分别是3个文件路径,其中每个参数的可能情况都有若干种。比如argv1可能有6个文件,argv2有100个文件,argv3有2个文件。实验程序会计算并返回一个实数作为实验结果。


现在为了测试各种不同参数下实验结果是怎样的,并且为了将来画图,我要把每种参数组合都跑一边。懂点数学的人可以看出,实际上我程序接受的参数是一个三元笛卡尔积。正常情况下写for循环跑一个单进程程序(我分不太清进程和线程),要跑6×100×2=1200次,于是我们就看到一个python进程疯狂运行,在任务管理器里看到它占用了25%的cpu资源,因为我电脑是双核4线程的。这样显然很慢。就算丢到服务器上,服务器cpu是24线程的,每个线程并不快,如果我的实验程序只用一个线程也不能发挥服务器的优势。

并行本来就是一个坑,python里写并行不太容易,还有啥GIL之类的,完全不想学。此外我程序每次运行之间完全没有关联,也不用共享什么内存,输出结果保存到数据库里就是了,用的不同主键也不会冲突。于是我决定用Windows批处理start一堆实例,参数不同。为了防止它一次启动1200个实例卡死,我还每隔24个线程执行一个带/wait参数的,这样程序会在第24个实例启动后等它完成再启动新的一批实例,这样同时运行的实例不会太多,会约等于24个左右。

废话不多说,上代码。


 f = open("test.bat")  
 i = 0  
 for a in a1List:  
   for b in a2List:  
     for c in a3List:  
       if i%24==23:  
         f.write("start /wait python test.py %s %s %s\n"(a,b,c))  
       else:  
         f.write("start python test.py %s %s %s\n"(a,b,c))  
       i=i+1  
 f.close()  
其中a1List等中存的是argv1所有可能输入的文件路径,a2List中存了argv2的100个可能输入的文件路径……
之后只要愉快地执行test.bat就可以了。


2016年4月29日星期五

试用docker版Huginn遇到Gem::RemoteFetcher::FetchError: SSL_connect...An error occurred while installing mysql2 (0.3.20...

由于我刚开始学习docker,而且不会ruby,下边用语不一定准确。

我试用了docker版的Huginn,而且是用的windows版docker toolbox运行的,按照官方文档执行
4. Start your Huginn container using docker run -it -p 3000:3000 cantino/huginn
后来经过我研究,实际上它启动时会默认执行/scripts/init
遇到了这个错误:
Gem::RemoteFetcher::FetchError: SSL_connect...
An error occurred while installing mysql2 (0.3.20...
似乎是在安装mysql2的gem这步挂了。原因是因为在大天朝局域网连不到那个服务器。

我首先尝试给docker的容器或者docker machine从环境变量设置proxy,但是没有效果。
后尝试如下方法成功:

  1.  docker run -it -p 3000:3000 cantino/huginn /bin/bash
    这一命令效果是:不是默认执行默认的/scripts/init,而是启动一个shell
  2.  export http_proxy=192.168.99.1:1080
  3.  export https_proxy=192.168.99.1:1080
    这一命令的效果是在启动的容器里用环境变量设置代理,代理的地址指向的是宿主机windows的shadowsocks,在容器中运行route和ifconfig是看不到这个地址的。但是可以进入docker machine里(执行docker-machine ssh default进入)看到我宿主机的地址是192.168.99.1。这也使我了解了windows下用docker toolbox的三层从下到上的关系大概是是windows——docker machine——docker容器
  4. 在/app下执行bundle
    这步安装依赖,实际上在init里就是执行这个的时候挂了。
  5. 执行/scripts/init
    这两步实际上应该有更巧妙的办法,比如把环境变量写到init里什么的,然而init我看不懂,还是不乱动了。