python开发之基于thread线程搜索本地文件的方法

本文实例讲述了python开发之基于thread线程搜索本地文件的方法。分享给大家供大家参考,具体如下:

先来看看运行效果图:

利用多个线程处理搜索的问题,我们可以发现他很快….

下面是代码部分:

# a parallelized “find(1)” using the thread module.
# this demonstrates the use of a work queue and worker threads.
# it really does do more stats/sec when using multiple threads,
# although the improvement is only about 20-30 percent.
# (that was 8 years ago. in 2002, on linux, i can’t measure
# a speedup. 🙁 )
# i’m too lazy to write a command line parser for the full find(1)
# command line syntax, so the predicate it searches for is wired-in,
# see function selector() below. (it currently searches for files with
# world write permission.)
# usage: parfind.py [-w nworkers] [directory] …
# default nworkers is 4
import sys
import getopt
import time
import os
from stat import *
import _thread as thread
# work queue class. usage:
# wq = workq()
# wq.addwork(func, (arg1, arg2, …)) # one or more calls
# wq.run(nworkers)
# the work is done when wq.run() completes.
# the function calls executed by the workers may add more work.
# don’t use keyboard interrupts!
class workq:
# invariants:
# – busy and work are only modified when mutex is locked
# – len(work) is the number of jobs ready to be taken
# – busy is the number of jobs being done
# – todo is locked iff there is no work and somebody is busy
def __init__(self):
self.mutex = thread.allocate()
self.todo = thread.allocate()
self.todo.acquire()
self.work = []
self.busy = 0
def addwork(self, func, args):
job = (func, args)
self.mutex.acquire()
self.work.append(job)
self.mutex.release()
if len(self.work) == 1:
self.todo.release()
def _getwork(self):
self.todo.acquire()
self.mutex.acquire()
if self.busy == 0 and len(self.work) == 0:
self.mutex.release()
self.todo.release()
return none
job = self.work[0]
del self.work[0]
self.busy = self.busy + 1
self.mutex.release()
if len(self.work) > 0:
self.todo.release()
return job
def _donework(self):
self.mutex.acquire()
self.busy = self.busy – 1
if self.busy == 0 and len(self.work) == 0:
self.todo.release()
self.mutex.release()
def _worker(self):
time.sleep(0.00001) # let other threads run
while 1:
job = self._getwork()
if not job:
break
func, args = job
func(*args)
self._donework()
def run(self, nworkers):
if not self.work:
return # nothing to do
for i in range(nworkers-1):
thread.start_new(self._worker, ())
self._worker()
self.todo.acquire()
# main program
def main():
nworkers = 4
#print(getopt.getopt(sys.argv[1:], ‘-w:’))
opts, args = getopt.getopt(sys.argv[1:], ‘-w:’)
for opt, arg in opts:
if opt == ‘-w’:
nworkers = int(arg)
if not args:
#print(os.curdir)
args = [os.curdir]
wq = workq()
for dir in args:
wq.addwork(find, (dir, selector, wq))
t1 = time.time()
wq.run(nworkers)
t2 = time.time()
sys.stderr.write(‘total time %r sec.\n’ % (t2-t1))
# the predicate — defines what files we look for.
# feel free to change this to suit your purpose
def selector(dir, name, fullname, stat):
# look for world writable files that are not symlinks
return (stat[st_mode] & 0o002) != 0 and not s_islnk(stat[st_mode])
# the find procedure — calls wq.addwork() for subdirectories
def find(dir, pred, wq):
try:
names = os.listdir(dir)
except os.error as msg:
print(repr(dir), ‘:’, msg)
return
for name in names:
if name not in (os.curdir, os.pardir):
fullname = os.path.join(dir, name)
try:
stat = os.lstat(fullname)
except os.error as msg:
print(repr(fullname), ‘:’, msg)
continue
if pred(dir, name, fullname, stat):
print(fullname)
if s_isdir(stat[st_mode]):
if not os.path.ismount(fullname):
wq.addwork(find, (fullname, pred, wq))
# call the main program
main()

希望本文所述对大家python程序设计有所帮助。

Posted in 未分类

发表评论