1月 02

python tornado异步处理记录

单进程单线程。

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        time.sleep(10)
        return "ok"

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(58000)
    tornado.ioloop.IOLoop.instance().start()

异步写法

#!/bin/env python
# -*- coding:utf-8 -*-
# Date:        2017-01-02
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
## END INIT INFO
import tornado.ioloop
import tornado.web
import tornado.gen
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带;在python2需要安装pip install futures
from concurrent.futures import ThreadPoolExecutor
import time

class MainHandler(tornado.web.RequestHandler):
    #executor 是局部变量  不是全局的
    executor = ThreadPoolExecutor(5)
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        res = yield self.sleep()
        self.write("wait. %s" % res)
        # 必须要结束
        self.finish()

    @run_on_executor
    def sleep(self):
        time.sleep(10)
        return "ok"

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(58000)
    tornado.ioloop.IOLoop.instance().start()

来源:http://www.dongwm.com/archives/shi-yong-tornadorang-ni-de-qing-qiu-yi-bu-fei-zu-sai/

11月 10

raspberry pi 2用golang 控制GPIO

raspberry pi2散热量并不大,但是长时间高运算量运行还是装个小风扇比较好,所以做个自动开关的风扇。本次使用go 1.7。
硬件:4针热敏传感器模块,宝上买的1块5,采用NTC热敏电阻传感器。小风扇还没有到,用led实验。
首先安装需要库
go get github.com/stianeikeland/go-rpio
查看源码可以对Linux的文件系统有更好的了解,推荐要好好看看。
代码部分:

/*
# Date:        2016-11-10
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
*/
package main

import (
    "os"
    "github.com/stianeikeland/go-rpio"
    "time"
)

var (
    aio = rpio.Pin(14)
    fio = rpio.Pin(4)
    alertCount int = 0
)

// 风扇端口
func fWrite(status string){
    fio.Output()
    if status == "high"{
        fio.High()
    }else if status == "low"{
        fio.Low()
    }
}

// 监控端口
func aRead() int{
    aio.Input()
    return int(aio.Read())
}

func main() {
    err := rpio.Open()
    if err != nil {
        os.Exit(1)
    }
    defer rpio.Close()
    // 因为没有while 直接用for
    for {
        // 数字不能太大
        // 1是内存问题,2是停止风扇范围
        if aRead() == 1 {
            if alertCount > 0{
                alertCount -= 1
            }
        }else{
            if alertCount <= 10{
                alertCount += 1
            }
        }
        //print(alertCount, "   ", aRead(), "\n")
        //
        if alertCount > 3{
            fWrite("high")
        } else {
            fWrite("low")
        }
        // 每次次循环等待一秒钟
        time.Sleep(1000 * time.Millisecond)
    }
}

imhot20161110
运行后实验,用手加热
qidong20161101
放开手
tingzhi20161110
raspberry pi2 接口图

raspberry pi2

raspberry pi2

8月 19

Linux 暴力破解rar密码 性能查看

python使用自带的性能分析工具。
生成报告
# python -m cProfile -o test1.out decRAR.py tt.rar passwd.txt
tt.rar pass is 123

查看报告
# python -c “import pstats; p=pstats.Stats(‘test1.out’); p.print_stats()”
Sat Jul 30 10:07:38 2016 test1.out

305 function calls in 2.922 seconds

Random listing order was used

ncalls tottime percall cumtime percall filename:lineno(function)
50 0.001 0.000 0.001 0.000 {method ‘close’ of ‘file’ objects}
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/site.py:357(__call__)
49 0.000 0.000 0.000 0.000 {method ‘find’ of ‘str’ objects}
49 0.006 0.000 2.919 0.060 /usr/lib64/python2.7/commands.py:56(getstatusoutput)
49 0.001 0.000 2.920 0.060 /usr/lib64/python2.7/commands.py:48(getoutput)
49 0.012 0.000 0.012 0.000 {posix.popen}
49 2.900 0.059 2.900 0.059 {method ‘read’ of ‘file’ objects}
1 0.000 0.000 0.000 0.000 {open}
2 0.000 0.000 0.000 0.000 {method ‘split’ of ‘str’ objects}
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/warnings.py:14(warnpy3k)
1 0.000 0.000 2.922 2.922 decRAR.py:8()
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/commands.py:20()
1 0.000 0.000 0.000 0.000 {method ‘disable’ of ‘_lsprof.Profiler’ objects}
1 0.000 0.000 0.000 0.000 {method ‘readlines’ of ‘file’ objects}
1 0.002 0.002 2.922 2.922 decRAR.py:13(main)

结论,密码有49个,所以调用解密命令49次,时间用在读文件上,就是解密部分。这样单进程单线程的结果应该已经是最佳了。

golang
不用协程部分,把main修改如下。

func main() {
    start()
    fmt.Println("not find password")
}

# time go run decRAR.go
tt.rar pass is 123
exit status 1

real 0m3.462s
user 0m3.117s
sys 0m0.291s
golang性能分析软件暂时没有用到。

8月 18

Linux 暴力破解rar密码

制作一个有简单密码的rar。简单密码表49行,正确密码在最后一行。暴力破解代码如下。
rar密码吗测试使用命令调用rarlinux方式测试,http://www.simonzhang.net/?p=2980

python部分

#!/bin/env python
# -*- coding:utf-8 -*-
# Date:        2016-07-29
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
import os
import sys
import commands


def main(rarName, passwd):
    try:
        passFile = open(passwd, 'rb').readlines()
    except:
        print "read password error"
    #
    num = 0
    for one in passFile:
        num += 1
        if num%1000 == 0:
            print "test %s" % num
        if one[-1] == '\n':
            one = one[:-1]
        getContext = commands.getoutput('rar t %s -p"%s"' % (rarName, one))
        if getContext.find("OK") > -1:
            print "%s pass is %s" % (rarName, one)
            exit()

if __name__ == "__main__":
    try:
        if sys.argv[1].split('.')[1] == "rar":
            rarName = sys.argv[1]
        else:
            print "rar name error"
            print "python devRAR.py xx.rar pass.txt"
            exit()
        if sys.argv[2].split('.')[1] == "txt":
            passwd = sys.argv[2]
        else:
            print "password error"
            print "python devRAR.py xx.rar pass.txt"
            exit()
    except:
        print "python devRAR.py xx.rar pass.txt"
        exit()
    main(rarName, passwd)

golang部分

/*
# Date:        2016-07-29
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
*/
package main

import (
   "os"
   "io"
   "fmt"
   "strings"
   "bufio"
   "os/exec"
   "runtime"
)

func checkRAR(passwd string) {
    var tmpPass string = "-p"+passwd
    cmd := exec.Command("rar", "t", "tt.rar", tmpPass)
    status := cmd.Run()
    if (status == nil){ 
        fmt.Println("tt.rar pass is ", passwd)
        os.Exit(1)
    }
}

func start(c chan string){
    // 读密码文件
    passFile := "passwd.txt"
    pf,err := os.Open(passFile)
    if err != nil {
        fmt.Println(passFile,err)
        os.Exit(1)
    }
    defer pf.Close()
    //
    rd := bufio.NewReader(pf)
    for {
        //以'\n'为结束符读入一行
        line, err := rd.ReadString('\n')
        if err != nil || io.EOF == err {
            break
        }
        tmpPass := strings.Replace(line, "\n", "", -1)
        /* 如果是Linux上编辑的密码文件下步不需要。
           如果密码文本是在windows下编辑的可能会带^M
           不可见字符。应用vim -v 或者cat -A 可以看到。
        */
        tmpPass = strings.Replace(tmpPass, "\r", "", -1)
        checkRAR(tmpPass) 
    } 
}

func main() {
    //计算cpu核数
    var loopnum int = runtime.NumCPU()
    //设置协程cpu核数
    runtime.GOMAXPROCS(loopnum)
    c := make(chan string)
    for i:=0; i<=loopnum; i++ {
        go start(c)
    }
    <- c
    fmt.Println("not find password")
}

源码部分

# time python decRAR.py tt.rar passwd.txt
tt.rar pass is 123

real 0m2.861s
user 0m2.535s
sys 0m0.279s

# time ./decRAR
tt.rar pass is 123

real 0m5.736s
user 0m5.151s
sys 0m0.452s

参数输入部分还没有开发,如果全部实现,golang应该超出python代码一倍多。
python运行时使用cpu 2%,可以改为多线程,这样开30个线程效果应该不错。
golang速度慢稍后再做性能分析,看看具体问题。

8月 02

单片机死机问题

单片器IO控制H桥马达驱动板,带动电机。很小的一个程序,但是跑不了多久就死机。
单片机硬件死机基本不可能。代码下断点多次也没有问题。用软件跑debug模式也没有。
硬件接led模拟测试2个小时也没有问题。最后驱动板调用,然后用led显示执行位置。
发现都是在电机停后就不能启动了,是单片机没有发送控制命令。如果单片机没有坏,就是
其它部件的问题。先换了一个晶振,跑了两个小时都没有。然后把之前晶振插回来,跑
了24小时也没有问题。因为马达和单片机放在一块板子上,估计是马达震动导致晶振松动。
有些棘手的问题真是二呀。