首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程处理、多处理错误

线程处理、多处理错误
EN

Stack Overflow用户
提问于 2012-07-09 01:25:35
回答 2查看 185关注 0票数 0

它和Windows上的finder一样,但是使用线程来获得更快的速度,

代码语言:javascript
复制
    import os,threading,multiprocessing


    def finder(path,q):
     for x in os.walk(unicode(path)):
      if x[1]:
       for dirname in x[1]:
        if target in dirname.lower():
         q.put(os.path.join(x[0],dirname))
      if x[2]:
       for name in x[2]:
        if target in name.lower():
         q.put(os.path.join(x[0],name))

     q.put(1)

    def printer(q):
     cmd=0
     while 1:
      tmp=q.get()
      if tmp==1:
       cmd += 1
       continue
      if cmd ==thnum:
       break
      print tmp

    if __name__ =="__main__":
     q=multiprocessing.JoinableQueue()
     ini=os.walk(u"C:\\").next()
     thnum=len(ini[1])
     target=raw_input("what you wanna get\n")

     p=multiprocessing.Process(target=printer,args=(q,))
     p.daemon=1
     p.start()

     for i in xrange(thnum):
      t=threading.Thread(target=finder,args=(ini[1][i],q,))
      t.start()
      print i," started"
     q.join()

它显示了

0开始1开始..。22开始

但没有给出结果所以我的问题是

  1. 为什么结果没有显示
  2. 我知道代码很脏:(...is是一种干净的方法吗?)

谢谢你们。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-09 01:53:45

这里只有一大堆乱七八糟的代码,还有一些错误。我看到的主要问题是,您的线程立即无法从它们的os.walk中生成任何内容,并直接退出q.put。这是因为您没有向每个线程传递完整的路径。只有一个目录名。但是很难知道这一点,因为您没有为任何变量使用描述性名称。

以下是一个经过清理的版本:

代码语言:javascript
复制
import os
import threading
import multiprocessing


def finder(path, q, done):
    for root, dirs, files in os.walk(unicode(path)):
        for dirname in dirs:
            if target in dirname.lower():
                q.put(os.path.join(root,dirname))
        for name in files:
            if target in name.lower():
                q.put(os.path.join(root,name))

    # print "Leaving thread", threading.current_thread()
    done.put(1)

def printer(q,done,worker_count):
    total = 0
    while 1:
        try: done.get_nowait()
        except: pass
        else: total += 1

        if total == worker_count:
            break

        try: tmp=q.get(timeout=1)
        except: pass

        print tmp

if __name__ =="__main__":

    results = multiprocessing.Queue()
    done = multiprocessing.Queue()
    root, dirs, files = os.walk(u"C:\\").next()
    thnum=len(dirs)
    target=raw_input("what you wanna get\n")

    p=multiprocessing.Process(target=printer,args=(results,done,thnum))
    p.start()

    for i in xrange(thnum):
        full_path = os.path.join(root, dirs[i])
        t=threading.Thread(target=finder,args=(full_path, results, done))
        t.start()

    p.join()

在发送到每个线程之前,看看我是如何将完整的路径连接到主块中的吗?我删除了JoinableQueue,因为它永远不会像你想的那样做。如果打印机在任何时候清除了结果队列,但线程仍然试图找到更多,队列将认为已完成并退出。我用另一个队列来代替它作为信号。完成后,每个工作人员都会在队列中放置一项。然后打印机继续检查是否能够从完成队列中提取足够的信号,以与启动的工人数量相等。如果是这样,它就会退出。

这整件事还可以重写得更好,但我只是给你的东西涂上了绷带。我只是把这个和你的东西放在一起。

注意,您开始整个过程的方式,检查起始路径下的目录,如果只有文件,基本上就会退出。

票数 2
EN

Stack Overflow用户

发布于 2012-07-09 01:44:13

第二,要编写干净的多线程代码,使用修饰器可以帮助您,并使它在线程和进程之间切换。

查看这里的示例,装饰器异步装饰器

您可以通过以下方式安装这些装饰器:

代码语言:javascript
复制
 easy_install decorator

或者使用python setup.py install下载代码

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11388135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档