ubuntu安装bochs笔记

$ sudo apt-get install build-essential xorg-dev libgtk2.0-dev 编译bochs $ ./configure --enable-debugger --enable-disasm $ sudo make $ sudo make install 记录几个目录: /usr/local/bin/bochs Bochs启动程序 /usr/local/bin/bximage Bochs带的制作磁盘镜像文件的工具 /usr/local/share/doc/bochsrc-sample.txt Bochs的配置文件例子 配置文件官方给的例子有详细的解释,修改一下就好。比如我编译的bochs的版本为 bochs-2.5.1,提示错误: device: hd message:ata0-0:could not open hard drive image file '30M.sample' 你可以新建一个hd img 也可以把配置文件里hd注释掉,再修改一下boot就好了. 这样安装的bochs带有调试功能,如果你想直接运行,可以执行c命令。 [caption id="attachment_698" align="alignnone" width="227" caption="ubuntu bochs调试"]ubuntu bochs调试[/caption]
Read more...

python 持久性管理-pickle模块介绍

什么是持久性? 持 久性的基本思想很简单。假定有一个 Python 程序,它可能是一个管理日常待办事项的程序,您希望在多次执行这个程序之间可以保存应用程序对象(待办事项)。换句话说,您希望将对象存储在磁盘上,便于 以后检索。这就是持久性。要达到这个目的,有几种方法,每一种方法都有其优缺点。 例如,可以将对象数据存储在某种格式的文本文件中,譬如 CSV 文件。或者可以用关系数据库,譬如 Gadfly、MySQL、PostgreSQL 或者 DB2。这些文件格式和数据库都非常优秀,对于所有这些存储机制,Python 都有健壮的接口。 这 些存储机制都有一个共同点:存储的数据是独立于对这些数据进行操作的对象和程序。这样做的好处是,数据可以作为共享的资源,供其它应用程序使用。缺点 是,用这种方式,可以允许其它程序访问对象的数据,这违背了面向对象的封装性原则 — 即对象的数据只能通过这个对象自身的公共(public)接口来访问。 另外,对于某些应用程序,关系数据库 方法可能不是很理想。尤其是,关系数据库不理解对象。相反,关系数据库会强行 使用自己的类型系统和关系数据模型(表),每张表包含一组元组(行),每行包含具有固定数目的静态类型字段(列)。如果应用程序的对象模型不能够方便地转 换到关系模型,那么在将对象映射到元组以及将元组映射回对象方面,会碰到一定难度。这种困难常被称为阻碍性不匹配(impedence- mismatch)问题。 一些经过 pickle 的 Python pickle 模块及其同类模块 cPickle 向 Python 提供了 pickle 支持。后者是用 C 编码的,它具有更好的性能,对于大多数应用程序,推荐使用该模块。我们将继续讨论 pickle ,但本文的示例实际是利用了 cPickle 。由于其中大多数示例要用 Python shell 来显示,所以先展示一下如何导入 cPickle ,并可以作为 pickle 来引用它: >>> import cPickle as pickle 现在已经导入了该模块,接下来让我们看一下 pickle 接口。 pickle 模块提供了以下函数对: dumps(object) 返回一个字符串,它包含一个 pickle 格式的对象; loads(string) 返回包含在 pickle 字符串中的对象; dump(object, file) 将对象写到文件,这个文件可以是实际的物理文件,但也可以是任何类似于文件的对象,这个对象具有 write() 方法,可以接受单个的字符串参数; load(file) 返回包含在 pickle 文件中的对象。 缺省情况下, dumps() 和 dump() 使用可打印的 ASCII 表示来创建 pickle。两者都有一个 final 参数(可选),如果为 True ,则该参数指定用更快以及更小的二进制表示来创建 pickle。 loads() 和 load() 函数自动检测 pickle 是二进制格式还是文本格式。 清单 1 显示了一个交互式会话,这里使用了刚才所描述的 dumps() 和 loads() 函数: 清单 1. dumps() 和 loads() 的演示
Welcome To PyCrust 0.7.2 - The Flakiest Python Shell
Sponsored by Orbtech - Your source for Python programming expertise.
Python 2.2.1 (#1, Aug 27 2002, 10:22:32)
[GCC 3.2 (Mandrake Linux 9.0 3.2-1mdk)] on linux-i386
Type "copyright", "credits" or "license" for more information.
>>> import cPickle as pickle
>>> t1 = ('this is a string', 42, [1, 2, 3], None)
>>> t1
('this is a string', 42, [1, 2, 3], None)
>>> p1 = pickle.dumps(t1)
>>> p1
"(S'this is a string'\nI42\n(lp1\nI1\naI2\naI3\naNtp2\n."
>>> print p1
(S'this is a string'
I42
(lp1
I1
aI2
aI3
aNtp2
.
>>> t2 = pickle.loads(p1)
>>> t2
('this is a string', 42, [1, 2, 3], None)
>>> p2 = pickle.dumps(t1, True)
>>> p2
'(U\x10this is a stringK*]q\x01(K\x01K\x02K\x03eNtq\x02.'
>>> t3 = pickle.loads(p2)
>>> t3
('this is a string', 42, [1, 2, 3], None)
注:该文本 pickle 格式很简单,这里就不解释了。事实上,在 pickle 模块中记录了所有使用的约定。我们还应该指出,在我们的示例中使用的都是简单对象,因此使用二进制 pickle 格式不会在节省空间上显示出太大的效率。然而,在实际使用复杂对象的系统中,您会看到,使用二进制格式可以在大小和速度方面带来显著的改进。 接下来,我们看一些示例,这些示例用到了 dump() 和 load() ,它们使用文件和类似文件的对象。这些函数的操作非常类似于我们刚才所看到的 dumps() 和 loads() ,区别在于它们还有另一种能力 — dump() 函数能一个接着一个地将几个对象转储到同一个文件。随后调用 load() 来以同样的顺序检索这些对象。清单 2 显示了这种能力的实际应用: 清单 2. dump() 和 load() 示例
>>> a1 = 'apple'
>>> b1 = {1: 'One', 2: 'Two', 3: 'Three'}
>>> c1 = ['fee', 'fie', 'foe', 'fum']
>>> f1 = file('temp.pkl', 'wb')
>>> pickle.dump(a1, f1, True)
>>> pickle.dump(b1, f1, True)
>>> pickle.dump(c1, f1, True)
>>> f1.close()
>>> f2 = file('temp.pkl', 'rb')
>>> a2 = pickle.load(f2)
>>> a2
'apple'
>>> b2 = pickle.load(f2)
>>> b2
{1: 'One', 2: 'Two', 3: 'Three'}
>>> c2 = pickle.load(f2)
>>> c2
['fee', 'fie', 'foe', 'fum']
>>> f2.close()
Pickle 的威力 到目前为止,我们讲述了关于 pickle 方面的基本知识。在这一节,将讨论一些高级问题,当您开始 pickle 复杂对象时,会遇到这些问题,其中包括定制类的实例。幸运的是,Python 可以很容易地处理这种情形。 可移植性 从 空间和时间上说,Pickle 是可移植的。换句话说,pickle 文件格式独立于机器的体系结构,这意味着,例如,可以在 Linux 下创建一个 pickle,然后将它发送到在 Windows 或 Mac OS 下运行的 Python 程序。并且,当升级到更新版本的 Python 时,不必担心可能要废弃已有的 pickle。Python 开发人员已经保证 pickle 格式将可以向后兼容 Python 各个版本。事实上,在 pickle 模块中提供了有关目前以及所支持的格式方面的详细信息: 清单 3. 检索所支持的格式
>>> pickle.format_version
'1.3'
>>> pickle.compatible_formats
['1.0', '1.1', '1.2']
多个引用,同一对象 在 Python 中,变量是对象的引用。同时,也可以用多个变量引用同一个对象。经证明,Python 在用经过 pickle 的对象维护这种行为方面丝毫没有困难,如清单 4 所示: 清单 4. 对象引用的维护
>>> a = [1, 2, 3]
>>> b = a
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> c = pickle.dumps((a, b))
>>> d, e = pickle.loads(c)
>>> d
[1, 2, 3, 4]
>>> e
[1, 2, 3, 4]
>>> d.append(5)
>>> d
[1, 2, 3, 4, 5]
>>> e
[1, 2, 3, 4, 5]
循环引用和递归引用 可以将刚才演示过的对象引用支持扩展到 循环引用(两个对象各自包含对对方的引用)和 递归引用(一个对象包含对其自身的引用)。下面两个清单着重显示这种能力。我们先看一下递归引用: >清单 5. 递归引用
>>> l = [1, 2, 3]
>>> l.append(l)
>>> l
[1, 2, 3, [...]]
>>> l[3]
[1, 2, 3, [...]]
>>> l[3][3]
[1, 2, 3, [...]]
>>> p = pickle.dumps(l)
>>> l2 = pickle.loads(p)
>>> l2
[1, 2, 3, [...]]
>>> l2[3]
[1, 2, 3, [...]]
>>> l2[3][3]
[1, 2, 3, [...]]
现在,看一个循环引用的示例: 清单 6. 循环引用
>>> a = [1, 2]
>>> b = [3, 4]
>>> a.append(b)
>>> a
[1, 2, [3, 4]]
>>> b.append(a)
>>> a
[1, 2, [3, 4, [...]]]
>>> b
[3, 4, [1, 2, [...]]]
>>> a[2]
[3, 4, [1, 2, [...]]]
>>> b[2]
[1, 2, [3, 4, [...]]]
>>> a[2] is b
1
>>> b[2] is a
1
>>> f = file('temp.pkl', 'w')
>>> pickle.dump((a, b), f)
>>> f.close()
>>> f = file('temp.pkl', 'r')
>>> c, d = pickle.load(f)
>>> f.close()
>>> c
[1, 2, [3, 4, [...]]]
>>> d
[3, 4, [1, 2, [...]]]
>>> c[2]
[3, 4, [1, 2, [...]]]
>>> d[2]
[1, 2, [3, 4, [...]]]
>>> c[2] is d
1
>>> d[2] is c
1
注意,如果分别 pickle 每个对象,而不是在一个元组中一起 pickle 所有对象,会得到略微不同(但很重要)的结果,如清单 7 所示: 清单 7. 分别 pickle vs. 在一个元组中一起 pickle
>>> f = file('temp.pkl', 'w')
>>> pickle.dump(a, f)
>>> pickle.dump(b, f)
>>> f.close()
>>> f = file('temp.pkl', 'r')
>>> c = pickle.load(f)
>>> d = pickle.load(f)
>>> f.close()
>>> c
[1, 2, [3, 4, [...]]]
>>> d
[3, 4, [1, 2, [...]]]
>>> c[2]
[3, 4, [1, 2, [...]]]
>>> d[2]
[1, 2, [3, 4, [...]]]
>>> c[2] is d
0
>>> d[2] is c
0
相等,但并不总是相同 正如在上一个示例所暗示的,只有在这些对象引用内存中同一个对象时,它们才是相同的。在 pickle 情形中,每个对象被恢复到一个与原来对象相等的对象,但不是同一个对象。换句话说,每个 pickle 都是原来对象的一个副本: 清单 8. 作为原来对象副本的被恢复的对象
>>> j = [1, 2, 3]
>>> k = j
>>> k is j
1
>>> x = pickle.dumps(k)
>>> y = pickle.loads(x)
>>> y
[1, 2, 3]
>>> y == k
1
>>> y is k
0
>>> y is j
0
>>> k is j
1
同时,我们看到 Python 能够维护对象之间的引用,这些对象是作为一个单元进行 pickle 的。然而,我们还看到分别调用 dump() 会使 Python 无法维护对在该单元外部进行 pickle 的对象的引用。相反,Python 复制了被引用对象,并将副本和被 pickle 的对象存储在一起。对于 pickle 和恢复单个对象层次结构的应用程序,这是没有问题的。但要意识到还有其它情形。 值得指出的是,有一个选项确实允许分别 pickle 对象,并维护相互之间的引用,只要这些对象都是 pickle 到同一文件即可。 pickle 和 cPickle 模块提供了一个 Pickler (与此相对应是 Unpickler ),它能够跟踪已经被 pickle 的对象。通过使用这个 Pickler ,将会通过引用而不是通过值来 pickle 共享和循环引用: 清单 9. 维护分别 pickle 的对象间的引用
>>> f = file('temp.pkl', 'w')
>>> pickler = pickle.Pickler(f)
>>> pickler.dump(a)

>>> pickler.dump(b)

>>> f.close()
>>> f = file('temp.pkl', 'r')
>>> unpickler = pickle.Unpickler(f)
>>> c = unpickler.load()
>>> d = unpickler.load()
>>> c[2]
[3, 4, [1, 2, [...]]]
>>> d[2]
[1, 2, [3, 4, [...]]]
>>> c[2] is d
1
>>> d[2] is c
1
不可 pickle 的对象 一 些对象类型是不可 pickle 的。例如,Python 不能 pickle 文件对象(或者任何带有对文件对象引用的对象),因为 Python 在 unpickle 时不能保证它可以重建该文件的状态(另一个示例比较难懂,在这类文章中不值得提出来)。试图 pickle 文件对象会导致以下错误: 清单 10. 试图 pickle 文件对象的结果
>>> f = file('temp.pkl', 'w')
>>> p = pickle.dumps(f)
Traceback (most recent call last):
  File "", line 1, in ?
  File "/usr/lib/python2.2/copy_reg.py", line 57, in _reduce
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
类实例 与 pickle 简单对象类型相比,pickle 类实例要多加留意。这主要由于 Python 会 pickle 实例数据(通常是 _dict_ 属性)和类的名称,而不会 pickle 类的代码。当 Python unpickle 类的实例时,它会试图使用在 pickle 该实例时的确切的类名称和模块名称(包括任何包的路径前缀)导入包含该类定义的模块。另外要注意,类定义必须出现在模块的最顶层,这意味着它们不能是嵌套 的类(在其它类或函数中定义的类)。 当 unpickle 类的实例时,通常不会再调用它们的 _init_() 方法。相反,Python 创建一个通用类实例,并应用已进行过 pickle 的实例属性,同时设置该实例的 _class_ 属性,使其指向原来的类。 对 Python 2.2 中引入的新型类进行 unpickle 的机制与原来的略有不同。虽然处理的结果实际上与对旧型类处理的结果相同,但 Python 使用 copy_reg 模块的 _reconstructor() 函数来恢复新型类的实例。 如果希望对新型或旧型类的实例修改缺省的 pickle 行为,则可以定义特殊的类的方法 _getstate_() 和 _setstate_() ,在保存和恢复类实例的状态信息期间,Python 会调用这些方法。在以下几节中,我们会看到一些示例利用了这些特殊的方法。 现在,我们看一个简单的类实例。首先,创建一个 persist.py 的 Python 模块,它包含以下新型类的定义: 清单 11. 新型类的定义
class Foo(object):
    def __init__(self, value):
        self.value = value
现在可以 pickle Foo 实例,并看一下它的表示: 清单 12. pickle Foo 实例
>>> import cPickle as pickle
>>> from Orbtech.examples.persist import Foo
>>> foo = Foo('What is a Foo?')
>>> p = pickle.dumps(foo)
>>> print p
ccopy_reg
_reconstructor
p1
(cOrbtech.examples.persist
Foo
p2
c__builtin__
object
p3
NtRp4
(dp5
S'value'
p6
S'What is a Foo?'
sb.
>>>
可以看到这个类的名称 Foo 和全限定的模块名称 Orbtech.examples.persist 都存储在 pickle 中。如果将这个实例 pickle 成一个文件,稍后再 unpickle 它或在另一台机器上 unpickle,则 Python 会试图导入 Orbtech.examples.persist 模块,如果不能导入,则会抛出异常。如果重命名该类和该模块或者将该模块移到另一个目录,则也会发生类似的错误。 这里有一个 Python 发出错误消息的示例,当我们重命名 Foo 类,然后试图装入先前进行过 pickle 的 Foo 实例时会发生该错误: 清单 13. 试图装入一个被重命名的 Foo 类的经过 pickle 的实例
>>> import cPickle as pickle
>>> f = file('temp.pkl', 'r')
>>> foo = pickle.load(f)
Traceback (most recent call last):
  File "", line 1, in ?
AttributeError: 'module' object has no attribute 'Foo'
在重命名 persist.py 模块之后,也会发生类似的错误: 清单 14. 试图装入一个被重命名的 persist.py 模块的经过 pickle 的实例
>>> import cPickle as pickle
>>> f = file('temp.pkl', 'r')
>>> foo = pickle.load(f)
Traceback (most recent call last):
  File "", line 1, in ?
ImportError: No module named persist
我们会在下面 模式改进这一节提供一些技术来管理这类更改,而不会破坏现有的 pickle。 特殊的状态方法 前面提到对一些对象类型(譬如,文件对象)不能进行 pickle。处理这种不能 pickle 的对象的实例属性时可以使用特殊的方法( _getstate_() 和 _setstate_() )来修改类实例的状态。这里有一个 Foo 类的示例,我们已经对它进行了修改以处理文件对象属性: 清单 15. 处理不能 pickle 的实例属性
class Foo(object):
    def __init__(self, value, filename):
        self.value = value
        self.logfile = file(filename, 'w')
    def __getstate__(self):
        """Return state values to be pickled."""
        f = self.logfile
        return (self.value, f.name, f.tell())
    def __setstate__(self, state):
        """Restore state from the unpickled state values."""
        self.value, name, position = state
        f = file(name, 'w')
        f.seek(position)
        self.logfile = f
模式改进 随 着时间的推移,您会发现自己必须要更改类的定义。如果已经对某个类实例进行了 pickle,而现在又需要更改这个类,则您可能要检索和更新那些实例,以便它们能在新的类定义下继续正常工作。而我们已经看到在对类或模块进行某些更改 时,会出现一些错误。幸运的是,pickle 和 unpickle 过程提供了一些 hook,我们可以用它们来支持这种模式改进的需要。 在 这一节,我们将探讨一些方法来预测常见问题以及如何解决这些问题。由于不能 pickle 类实例代码,因此可以添加、更改和除去方法,而不会影响现有的经过 pickle 的实例。出于同样的原因,可以不必担心类的属性。您必须确保包含类定义的代码模块在 unpickle 环境中可用。同时还必须为这些可能导致 unpickle 问题的更改做好规划,这些更改包括:更改类名、添加或除去实例的属性以及改变类定义模块的名称或位置。 类名的更改 要 更改类名,而不破坏先前经过 pickle 的实例,请遵循以下步骤。首先,确保原来的类的定义没有被更改,以便在 unpickle 现有实例时可以找到它。不要更改原来的名称,而是在与原来类定义所在的同一个模块中,创建该类定义的一个副本,同时给它一个新的类名。然后使用实际的新类 名来替代 NewClassName ,将以下方法添加到原来类的定义中: 清单 16. 更改类名:添加到原来类定义的方法
def __setstate__(self, state):
    self.__dict__.update(state)
    self.__class__ = NewClassName
当 unpickle 现有实例时,Python 将查找原来类的定义,并调用实例的 _setstate_() 方法,同时将给新的类定义重新分配该实例的 _class_ 属性。一旦确定所有现有的实例都已经 unpickle、更新和重新 pickle 后,可以从源代码模块中除去旧的类定义。 属性的添加和删除 这些特殊的状态方法 _getstate_() 和 _setstate_() 再一次使我们能控制每个实例的状态,并使我们有机会处理实例属性中的更改。让我们看一个简单的类的定义,我们将向其添加和除去一些属性。这是是最初的定义: 清单 17. 最初的类定义
class Person(object):
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname
假定已经创建并 pickle 了 Person 的实例,现在我们决定真的只想存储一个名称属性,而不是分别存储姓和名。这里有一种方式可以更改类的定义,它将先前经过 pickle 的实例迁移到新的定义: 清单 18. 新的类定义
class Person(object):
    def __init__(self, fullname):
        self.fullname = fullname
    def __setstate__(self, state):
        if 'fullname' not in state:
            first = ''
            last = ''
            if 'firstname' in state:
                first = state['firstname']
                del state['firstname']
            if 'lastname' in state:
                last = state['lastname']
                del state['lastname']
            self.fullname = " ".join([first, last]).strip()
        self.__dict__.update(state)
在这个示例,我们添加了一个新的属性 fullname ,并除去了两个现有的属性 firstname 和 lastname 。当对先前进行过 pickle 的实例执行 unpickle 时,其先前进行过 pickle 的状态会作为字典传递给 _setstate_() ,它将包括 firstname 和 lastname 属性的值。接下来,将这两个值组合起来,并将它们分配给新属性 fullname 。在这个过程中,我们删除了状态字典中旧的属性。更新和重新 pickle 先前进行过 pickle 的所有实例之后,现在可以从类定义中除去 _setstate_() 方法。 模块的修改 在概念上,模块的名称或位置的改变类似于类名称的改变,但处理方式却完全不同。那是因为模块的信息存储在 pickle 中,而不是通过标准的 pickle 接口就可以修改的属性。事实上,改变模块信息的唯一办法是对实际的 pickle 文件本身执行查找和替换操作。至于如何确切地去做,这取决于具体的操作系统和可使用的工具。很显然,在这种情况下,您会想备份您的文件,以免发生错误。但 这种改动应该非常简单,并且对二进制 pickle 格式进行更改与对文本 pickle 格式进行更改应该一样有效。 结束语 对象持久性依赖于底层编程语言的对象序列化能力。对于 Python 对象即意味着 pickle。Python 的 pickle 为 Python 对象有效的持久性管理提供了健壮的和可靠的基础。在下面的 参考资料中,您将会找到有关建立在 Python pickle 能力之上的系统的信息。原文链接:http://www.cnblogs.com/evening/archive/2012/04/01/2427876.html
Read more...

python多线程学习-post提交加密码生成

真正使用多线程进行程序的编写,以前学习时的笔记《python threading模块学习join()》,现在用在实践上。 写代码在发现对他不熟悉的时候,总是缩手缩脚的,不知道为什么也不去尝试一下。过分依赖搜索引擎,自从上次写golang读取id3信息的那个程序开始,学会了用英文关键字检索信息,会检索到很多有用的信息,像stackoverflow上的回答。 先介绍一下功能:多线程生成密码,多线程提交数据。密码是排列组合生产的,五个元素全排列5!,这个密码长度是5。5个元素,密码长度为2,5×4  。适合那种通用型密码的破解。 程序代码:
# encoding:utf-8
#
#author:0x55aa
#team:Pax.Mac Team
#time:2012.08.17
#
import urllib2,urllib,time
import threading
from Queue import Queue
from BeautifulSoup import BeautifulSoup

#提交的地址
URL = ""
#密码列表example:['0x55aa','1','b']
passwdlist = ['0x55aa','123','a']
#生产密码长度
passwdlen = 3

#密码生成完毕
passwd_done = False
#队列为空啦,这个可以用Queue.empty()
#post_done = False
#锁,用于输出
lock = threading.Lock()
#tag标识是否找到密码退出
tag = False

#密码
def perm(items, n=None):
    if n is None:
        n = len(items)
    for i in range(len(items)):
        v = items[i:i+1]
        if n == 1:
            yield v
        else:
            rest = items[:i] + items[i+1:]
            for p in perm(rest, n-1):
                yield v + p

def sqlPost(password):
    """提交奥"""
    #提交字段的设置在这里。。
    post_params = [
        ('UserName', 'root'),
        ('Password', password),
        ]
    data = urllib.urlencode(post_params)
    req = urllib2.Request(URL)
    r = urllib2.urlopen(req,data)

    #这里加入返回数据的判断
    """
    soup = BeautifulSoup(r.read())
    list1 = soup.find('value')
    """
    return list1

class PasswordProduce(threading.Thread):
    """生成密码"""
    def __init__(self,queue,first,items,n):
        threading.Thread.__init__(self)
        self.passwd = queue
        self.first = first
        self.items = items
        self.n = n

    def run(self):
        #生成密码
        r = perm(self.items,self.n)
        for i in r:
            p = self.first + ''.join(i)
            #密码插入队列
            self.passwd.put(p)
            """
            if lock.acquire():
                print p
                lock.release()
            """

class Sqlpost(threading.Thread):
    """提交"""
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.passwd = queue

    def run(self):
        #post提交
        global passwd_done
        while not (passwd_done and self.passwd.empty()):
            """
            if lock.acquire():
                print self.getName(),passwd_done , self.passwd.empty()
                lock.release()
            """
            #取得密码
            if not self.passwd.empty():
                p = self.passwd.get()
            else:
                time.sleep(2)
                continue
            """
            if lock.acquire():
                print p
                lock.release()
            """
            #提交
            r = sqlPost(p)
            #打印返回信息
            global tag
            if r:
                tag = True
            if lock.acquire():
                print "password:",p,">>the result:",r
                #print r
                lock.release()
            if tag:
                break

def main():

    queue = Queue()
    #密码线程
    passwdthread = []
    #post
    postthread = []

    #线程数
    s = len(passwdlist)
    for i in range(s):
        first = passwdlist[i]
        lastlist = passwdlist[:i]+passwdlist[i+1:]
        thelen = passwdlen - 1
        pp = PasswordProduce(queue,first,lastlist,thelen)
        sp = Sqlpost(queue)
        passwdthread.append(pp)
        postthread.append(sp)
        pp.start()
        sp.start()

    for t in passwdthread:
        t.join()
    #设置,密码生产完毕
    global passwd_done
    passwd_done = True

    print "\npassword is produced done\n"

    for t in postthread:
        t.join()

    print "\nAll done!\n"

if __name__ == '__main__':
    main()
排列组合代码Google而来,等再写一篇文章进行分析,这篇写多线程编程。 1.join方法的使用。可以参考上面这篇文章,在密码生产线程都结束后,进行passwd_done变量的设置。 2.queue的使用。queue可以方便的进行线程间的通信数据交换。生产密码添加到queue,post线程提交从队列中获取密码。这里有两个判断条件:passwd_done判断密码生产是否结束,self.passwd.empty()检查队列是否为空。当这两个条件都符合时,密码就全部跑完了。还有一个全局变量tag用于当密码成功后,结束线程。 3.密码为了多线程生成,我取其中一个元素作为密码的首位,也就是有len(passwdlist)个线程。不知道这里用什么方法实现好。 4.数据的打印用了threading.Lock()
Read more...

python用py2exe打包成exe

py2exe可以将python程序打包成exe,方便没有python环境的用户使用。 在目录下建立py文件setup.py写入代码:
#-*- coding:utf-8 -*-
from distutils.core import setup
import glob
import py2exe,sys,os

options = {"py2exe":
           {"dll_excludes": ["MSVCP90.dll"],
            "compressed": 1, #压缩
            "optimize": 2,
            #"ascii": 1,
            #"includes":includes,
            "bundle_files": 1 #所有文件打包成一个exe文件 }
            }
           }
setup(windows=[{"script": "mp3.py","icon_resources": [(1,"mp3.ico")]}],

      options=options,
      zipfile=None,#不生成library.zip文件

      )
然后执行:python setup.py py2exe就成功了。 这是第二次使用py2exe打包python程序,感觉生成的文件好大,写编译给别人用的程序还是vc来的实际。   主要参考:http://justcoding.iteye.com/blog/900993
Read more...

golang读取mp3文件的ID3信息

学习golang来自己写的代码,先贴出来。
package main
import (
    "fmt"
    "os"
    "errors"
    "strings"
)
//no tag 
var ErrFormat = errors.New("No TAG!")
type Mp3 struct{
    //the file attr
    Name string
    Size int64
    //the mp3 attr
    Title string
    Artist string
    Album string
    Year string
    Comment string
    Genre uint8
}
func (m *Mp3) PrintInfo(){
    fmt.Printf("%v:\n",m.Name)
    fmt.Printf("size:%v\ntitle:%v\nartist:%v\nalbum:%v\nyear:%v\ncomment:%v\n",m.Size,m.Title,m.Artist,m.Album,m.Year,m.Comment)
    fmt.Printf("genre:%v",m.Genre)
}
func (m *Mp3) GetInfo(filename string) (err error){
    id3 := make([]byte,128)
    //for read access.
    f,err := os.Open(filename)
    if err != nil{
        return
    }
    defer f.Close()
    //return FileInfo
    fileInfo,err := f.Stat()
    if err != nil{
        return
    }
    //the file size,int64
    m.Size = fileInfo.Size()
    //the file name,string. eq filename
    m.Name = fileInfo.Name()
    //if
    _,err = f.ReadAt(id3,m.Size-128)
    if err != nil{
        return
    }
    tag := string(id3[:3])
    if tag != "TAG"{
        //err  "No ID3~"
        return ErrFormat
    }
    m.Title = strings.Trim(string(id3[3:33]),"\x00")
    m.Album = strings.Trim(string(id3[33:63]),"\x00")
    m.Artist = strings.Trim(string(id3[63:93]),"\x00")
    m.Year = string(id3[93:97])
    m.Comment = strings.Trim(string(id3[97:127]),"\x00")
    m.Genre = uint8(id3[127])
    return nil
}
func main(){
    m := new(Mp3)

    f,err := os.Open(".")
    if err != nil{
        fmt.Print(err)
    }
    defer f.Close()
    names,err := f.Readdirnames(-1)
    if err != nil{
        fmt.Print(err)
    }
    for _,name := range names{
        a := strings.Split(name,".")
        fileExt := strings.ToLower(a[len(a)-1])
        //fmt.Print(i,fileExt)
        if fileExt == "mp3"{
            err = m.GetInfo(name)
            if err != nil{
                fmt.Print(name,err)
            }
            m.PrintInfo()
        }
    }
    //fmt.Printf("%v",names)
}
有关id3的介绍,程序只读取id3 vi版本的信息,位于mp3文件末尾的128个字节。 数据结构定义如下: char Header[3]; /*标签头必须是"TAG"否则认为没有标签*/ char Title[30]; /*标题*/ char Artist[30]; /*作者*/ char Album[30]; /*专集*/ char Year[4]; /*出品年代*/ char Comment[30]; /*备注*/ char Genre; /*类型*/ ID3V1的各项信息都是顺序存放,没有任何标识将其分开,比如标题信息不足30个字节,则使用'\0'补足,否则将造成信息错误。
Read more...

Django的CSRF-Ajax

django中csrf的验证: Django是在post中有一个字段CsrfViewMiddleware 进行相关验证,验证过程很简单,从Cookie中拿出token,然后从POST中拿出csrfmiddlewaretoken,然后块俩做一个字符匹配。因为恶意网站无法读取你的Cookie(因为浏览器的同源策略),所以无法获得Cookie里的CSRF Token,无法伪造出csrf,POST就会失败,这样就不会产生安全问题。 ajax提交post表单时,从网上找到一个感觉不错的方法记录。
function getCookie(sName){
var aCookie=document.cookie.split("; ");
for(var i=0;i<aCookie.length;i++){var aCrumb=aCookie[i].split("=");if(sName==aCrumb[0])
return(aCrumb[1]);}return null;}
在需要提交表单的地方,加入的数据是getCookie('csrftoken') 字段名为csrfmiddlewaretoken
Read more...

erlang编程笔记-分布式编程

名字服务 功能:向服务器提交一个名字,然后服务器返回一个与这个名字关联的值。
-module(kvs).
-export([start/0,store/2,lookup/1]).

start() -> register(kvs,spawn(fun() -> loop() end)).
store(Key,Value) -> rpc({store,Key,Value}).
lookup(Key) -> rpc({lookup,Key}).

rpc(Q) ->
    kvs ! {self(),Q},
    receive
        {kvs,Reply} ->
            Reply
    end.
loop() ->
    receive
        {From,{store,Key,Value}} ->
            put(Key,{ok,Value}),
            From ! {kvs,true},
            loop();
        {From,{lookup,Key}} ->
            From ! {kvs,get(Key)},
            loop()
    end.
4> c(kvs.erl). {ok,kvs} 5> kvs:start(). true 6> kvs:store({location,joe},"Stockholm"). true 7> kvs:store(weather,raining). true 8> kvs:lookup(weather). {ok,raining} 10> kvs:lookup({location,joe}). {ok,"Stockholm"} 11> kvs:lookup({location,jane}). undefined 执行kvs:start(),将创建服务器进程,将接受消息并操作。匹配{From,{store,Key,Value}} 用于接收需要存储的键和值,存储后,给客户端发送保存成功的消息。 {From,{lookup,Key}}取得Key对应的值,并返回该值。 执行6句,将向服务进程发送key和value,第八句则是取值。 同一台机器上,客户端运行一个节点而服务端运行一个节点 需要打开两个终端。 启动一个名为s的erlang节点。并启动服务 D:\erlang5.9.1\code>erl -sname s@localhost (s@localhost)1> kvs:start(). true 启动名为a的erlang节点,然后使用erlang标准库模块prc来调用kvs模块中的函数。 D:\erlang5.9.1\code>erl -sname a@localhost (a@localhost)1> rpc:call(s@localhost,kvs,store,[weather,fine]). =PROGRESS REPORT==== 10-Aug-2012::11:53:03 === supervisor: {local,inet_gethost_native_sup} started: [{pid,<0.49.0>},{mfa,{inet_gethost_native,init,[[]]}}] =PROGRESS REPORT==== 10-Aug-2012::11:53:03 === supervisor: {local,kernel_safe_sup} started: [{pid,<0.48.0>}, {name,inet_gethost_native_sup}, {mfargs,{inet_gethost_native,start_link,[]}}, {restart_type,temporary}, {shutdown,1000}, {child_type,worker}] true (a@localhost)2> rpc:call(s@localhost,kvs,lookup,[weather]). {ok,fine} 在a节点验证weather的值 (s@localhost)2> kvs:lookup(weather). {ok,fine} 函数rpc:call(Node,Mod,Func,[Arg1,Arg2,...,])在Node上执行一个远程调用。被调用的函数是Mod:Func(Arg1,Arg2,...,).
Read more...

erlang并发编程-超时receive,注册进程

1.带超时的receive。 防止消息不来,receive语句陷入无限等待中。   只有超时的receive 功能:让当前进程暂停Tms。
sleep(T) ->
    receive
    after T ->
        true
    end.
超时时间为0的receive 超时时间为0的语句会立即触发一个超时,但在此之前,会尝试对邮箱进行模式匹配。
flush_buffer() ->
    receive
        _Any ->
	    flush_buffer()
    after 0 ->
        true
    end.
程序分析: 触发超时之前,会先进行模式匹配,_Any匹配到,又会调用flush_buffer(),一直到清空进程邮箱中的所有消息。 没有超时子句,在邮箱为空情况下,flush_buffer()会永久暂停,不会返回。
priority_receive() ->
    receive
        {alarm,X} ->
	    {alarm,X}
    after 0 ->
        receive
	    Any ->
	        Any
	end
    end.
触发超时前,进行模式匹配时,如果没有消息与{alarm,X}匹配那么执行后面会接收邮箱中的第一个消息。如果没有消息,会在内层的receive上暂停,然后返回它受到的第一个消息。 只有在邮箱中的消息都进行过模式匹配后才会检查after段是否需要进行运算。 2.注册进程。 4个BIF管理注册进程。 register(AnAtom,Pid) AnAtom为原子。注册进程Pid为原子AnAtom。如果该原子被另一个进程注册,那么注册失败。 unregister(AnAtom)移除对应的注册信息。如果一个注册进程死亡,那么也会自动取消注册。 whereis(AnAtom) -> Pid | undefined 判断原子是否被注册,如果被注册,返回进程id,如果没有被注册,返回原子undefined. registered() -> [AnAtom::atom()]返回系统中所有已经注册的名称列表。      
Read more...

golang学习笔记-接口

golang接口代码:
package main
import "fmt"
type S struct {
    i int
}
func (p *S) Get() int {
    return p.i
}
func (p *S) Put(v int){
    p.i = v
}
type I interface{
    Get() int
    Put(int)
}
func f(p I){
    fmt.Println(p.Get())
    p.Put(1)
}
func main(){
    var s S
    f(&s)
    fmt.Println(s.Get())

}
go代码分析: 开始定义了一个具有一个字段和两个方法的结构类型S 14-17行,定义了一个接口类型,他是方法的集合。对于接口I,S是其合法实现,因为结构S定义了I所需的两个方法。 往下,函数f()的参数为接口类型。p能够实现I,则有方法Get()和Put()。函数的功能是 打印字段i的值,和将i至1. main()函数中,因为S是I的合法实现,定义S类型的s,并将指针传入函数f()。 空接口 每个类型都能匹配空接口:interface{}.我们可以定义一个空接口作为参数的函数: func g(something interface{}) int { return something.(I).Get() } 这个函数中参数为interface{}空接口,能接受任何类型。.(I)是类型断言,用于转换something到I类型的接口。如果有这个类型,则可以调用Get()。 例如: s=new(S) fmt.Println(g(s)) 这个是成功的。创建S类型满足I,可以调用Get()。再看下面这个: i := 6 fmt.Println(g(i)) 这能编译通过,但运行会出错,因为内建类型int没有Get()方法。他不能实现I。 这种问题解决办法:
package main
import "fmt"
type S struct {
    i int
}
func (p *S) Get() int {
    return p.i
}
func (p *S) Put(v int){
    p.i = v
}
type I interface{
    Get() int
    Put(int)
}
func f(p I){
    fmt.Println(p.Get())
    p.Put(1)
}
func g(something interface{}){
    if t,ok := something.(I); ok{
        fmt.Println("I:",t.Get())
    }else if t,ok := something.(int); ok{
        fmt.Println("int:",t)
    }else{
        fmt.Println("not found:",something)
    }
}
func h(something interface{}){
    switch t:=something.(type){
        case I:
            fmt.Println("I:",t.Get())
        case int:
            fmt.Println("int:",t)
        case *S:
            fmt.Println("S:",t.Get())
        default:
            fmt.Println("not found:",something)
    }
}
func main(){
    var s S
    f(&s)
    fmt.Println(s.Get())
    g(&s)
    h(&s)
    i := 6
    g(i)
    h(i)
}
与上面相比添加了函数g()h(),与前面不同,这个没有返回值,我修改了一下把fmt.Println写到函数里面了。 g()函数里的switch语句。变量t保存了something的类型,在switch之外使用(type)是非法的。 这里还发现一个问题: 在type switch里不能使用fallthrough,使用时报错:.\9.go:33: cannot fallthrough in type switch 接口类型的方法 接口定义为一个方法的集合。方法包含实际的代码。换句话说,一个接口就是定义,而方法就是实现。 因此,接收者不能定义为接口类型,这样做的话会引起invalid receiver type ... 的编译器错误。 接收者类型必须是T或*T,这里的T是类型名。T叫做接收者基础类型或简称基础类型。基础类型一定不能使指针或接口类型,并且定义在与方法相同的包中。 接收者指 receiver 接口指针 在Go 中创建指向接口的指针是无意义的。实际上创建接口值的指针也是非法的。 var buf bytes.Buffer io.Copy(buf,os.Stdin) 就会复制标准输入到buf的副本,而不是buf本身。这看起来永远不会是一个期望的结果。
Read more...

golang笔记-Methods: a taste of OOP

方法:面向对象的味道 go代码:
package main
import (
    "fmt"
    "math"
)

type Rectangle struct{
    width,height float64
    rarea float64
}
type Circle struct{
    radius float64
}

func (r Rectangle) area() float64{
    return r.width * r.height
}
func (c Circle) area() float64{
    return c.radius * c.radius *math.Pi
}
func (r *Rectangle) setarea(a float64) {
    r.rarea = a
}
func (r Rectangle) setarea2(a float64) (Rectangle){
    r.rarea = a
    return r
}

func main(){
    r1 :=Rectangle{12,2,0}
    r1.setarea(r1.area())
    fmt.Println(r1.rarea)

    r2 := Rectangle{3,4,0}
    newr2 := r2.setarea2(r2.area())
    fmt.Println(r2.rarea)
    fmt.Println(newr2.rarea)
    c1 := Circle{10}
    c2 := Circle{2}
    fmt.Println("r1:",r1.area())
    fmt.Println(r2.area())
    fmt.Println(c1.area())
    fmt.Println(c2.area())

}
结果: D:\code>go run 7.go 24 0 12 r1: 24 12 314.1592653589793 12.566370614359172 代码中有两个同名方法area,他们前面括号里是ReceiverType,称作receiver。 拥有不同receiver的方法是不同的,即使他们有相同的名字。 内建类型不能定义方法,但是可以定义一个有方法的这种类型。如: type ages int setarea()修改了字段rarea的值,比较setarea()和setarea2(),会发现如果不使用指针,赋值操作是给了一个复制版的r, 并不是原来的值。 匿名字段代码:
package main
import "fmt"

type Human struct{
    name string
    age int
    phone string
}
type Employee struct{
    Human//Human类型的匿名字段
    speciality string
    phone string
}

func main(){
    Bob := Employee{Human{"bob",34,"777777-3"},"designer","33-22"}
    fmt.Println(Bob.name)
    fmt.Println(Bob.phone)
    fmt.Println(Bob.Human.phone)
    fmt.Println(Bob.Human.name)
}
运行结果: D:\code>go run 8.go bob 33-22 777777-3 bob 从程序中,当有字段冲突时,我们必须写全字段名称;当没有冲突时,两种方式都可以。
Read more...

Previous Page 1 2 3 4 5 6 7 8 9 10 Next Page 最后一页