博采众长,精于一技。Live for love, work for dream.

Python Queue阻塞引发变量污染

大家先来看一段代码:
# -*- coding: utf-8 -*-
'''
Created on 2012-3-01

@author: rebill
'''
from multiprocessing import JoinableQueue, Process
import time

class C1(Process):
    def __init__(self, queue):
        Process.__init__(self)
        self.queue = queue
        
    def run(self):
        for i in xrange(3):
            data = {'a':i}
            self.queue.put(data)
#            time.sleep(0.1)
            data['b'] = i
            self.queue.put(data)
    
class C2(Process):
    def __init__(self, queue):
        Process.__init__(self)
        self.queue = queue
        
    def run(self):
        while True:
            item = self.queue.get()
            if item != None:
                print item
                self.queue.task_done()        
    
if __name__ == '__main__':
    queue = JoinableQueue()
    
    c1 = C1(queue)
    c1.start()
    
    c2 = C2(queue)
    c2.start()
    
    queue.join()

预期的结果应该是这样:
{'a': 0}
{'a': 0, 'b': 0}
{'a': 1}
{'a': 1, 'b': 1}
{'a': 2}
{'a': 2, 'b': 2}

但事实往往出乎你的意料,真正的输出应该是:
{'a': 0, 'b': 0}
{'a': 0, 'b': 0}
{'a': 1, 'b': 1}
{'a': 1, 'b': 1}
{'a': 2, 'b': 2}
{'a': 2, 'b': 2}

为什么会导致变量被污染了呢?
细心的你,应该看到我注释的代码
time.sleep(0.1)

没错,Python的Queue会阻塞,不过又不是全阻塞,它是半阻塞。就算你把queue.put换成queue.put_nowait(),结果还是一样的。但是在实际的生产环境中,你不可能加上time.sleep(0.1)这样的代码,解决的办法就是将两次put的变量名换成不一样的,防止变量被污染。
像这样:
data_a = {'a':i}
self.queue.put(data_a)
data_b  = {'a':i, 'b':i}
self.queue.put(data_b)

或者你有什么其他更好的办法呢?欢迎一起探讨。

为非程序员准备的简洁Python语言教材

为非程序员准备的简洁Python语言教材,欢迎提问。
Python 的中文意思是巨蟒,大蟒蛇。

计算机编程主要概念

计算机语言编程的主要内容就这些:数字,文字,循环,公式,变量

数 字: 1, 2, 3, 5.6, 120, 32.4, 3.1415926, -3, -0.123
文字: 你好,我好,你太牛了,很黄很暴力,这类的文字。一般用双引号(")或者单引号(')括起来。术语叫字符串 ,就是一堆字符,串起来。
循环: 循环(loop)就是重复的做一件事。计算机是一个很笨的机器,基本上只会做加,减,乘,除,大于,小于,等于和循环这种简单的工作。编程就是把复杂的问 题,拆成简单的单元让它重复。
幸亏有下面讲到的公式,所以很多较复杂的问题已经有了解决方法,我们只是重 复的套用别人的解决公式就可以了,不用拆得太细。
Python 语言最大的优势,就是这个语言中包含了大量解决常见问题的公式,你想干的事,基本上都有人帮你干了,你只是需要把他们组织,捆绑起来就可以了。比如下载文 件的公式,分析网页内容的公式,压缩文件的公式,处理电子邮件的公式等等。
公式: 就像数学公式 (a+b)2= a2 + 2ab + b2 这种。算的时候带入具体数值,比如:(3+4)2 = 32 + 2*3*4 + 42 = 9+24+16 = 49 。前面的 (a+b)2 就是我们的公式名(当然编程时,我们会用一些比较容易明白的词组做为公式名,比如“和的平方”这种,英语或者拼音都可以),他需要两个参数a,b;后面的 a2 + 2ab + b2 是具体怎么算出来的步骤,这就是我们的公式内容。
在 计算机里,公式的术语叫“函数”或者“方法”。我们定义一个函数,就是定义一条公式,用的时候,拿来参数a,b什么 的,套一下公式就行了。
为了程序的结构清晰,我们往往会定义很多函数。把复杂的问题分成很多小问题,每个小问题放到一个函数 里,然后在解决复杂问题的函数里,使用这些小问题函数解决大问题。更重要的是我们可以大量的使用别人写好的函数来解决自己的问题。

继续阅读 »

适用于 PHP 开发人员的 Python 基础知识

您是一名 PHP 开发人员。您在过去 五年(或更长时间)中可能一直都编写应用程序,您已经将许多想像变成了可能 — 电子商务系统、简单内容管理系统、Twitter 和 Facebook 集成以及各种自定义实用工具。您可能还需要维护大量代码 — 从简单的显示页面到包含数千行其他人编写的代码的自定义应用程序,不一而足。
您已经在 PHP 上花费了大量时间,转向另一种语言势在必行。您也知道原地不动就意味着被动挨打。其实,学习新语言就像是去国外旅行:您会接触到新事物,品尝新食物,领略不同的文化,与不同的人对话,了解一切新奇,然后再回到家中体会原来的环境。
本文将带领您前往 Python 的世界遨游一番。本文假定您不具备 Python 编程语言的任何知识,但至少应具备一些基本的编程知识。我们将侧重于对 Python 和 PHP 进行比较 — 并不是为了分出两者孰优孰劣,而是因为一个简单的真理:在学习新知识时参照已有知识会更加轻松。
本文的目标相当简单:简要介绍 Python 的基本知识,为读者自己进行深入搜索打下基础。幸运的是,您将认识到 Python 实际上与您之前所使用的语言并无不同之处。再次以旅游为例,您并不需要到太远的地方,只需要去语言相通的邻国即可。

继续阅读 »

返回顶部