关于为什么Lock机制没有在下面的python脚本中实现的任何建议?

时间:2015-10-20 03:21:28

标签: python multithreading python-2.7 synchronization locking

我使用多线程匿名登录公共可用的FTP站点并列出主机名以及相应的目录。我使用threading.lock()方法做同样的事情,但它似乎没有工作,并随机打印主机和各自的目录。我哪里错了?以下是我正在运行的代码。

#!/usr/bin/python
import threading
import Queue
from ftplib import FTP

ftpSiteList = [ 'ftp.x.org', 'ftp4.FreeBSD.org', 'ftp.ncsa.uiuc.edu',    'ftp.crans.org' ]
threadsList = []

class workerClass(threading.Thread):
    def __init__(self,queue,tid):
            threading.Thread.__init__(self)
            self.queue = queue
            self.lock = threading.Lock()
            self.tid = tid
            print "Worker Thread %d reporting for Service !!!"%self.tid

   def run(self):
            self.lock.acquire()
            try:
                    while True:


                                    host = ''
                                    try:
                                            host = self.queue.get(timeout=1)
                                    except Queue.Empty:
                                            print "Worker thread %d exiting. "%(self.tid)
                                            return
                                    try:
                                            conn = FTP(host)
                                            conn.login()
                                            print 'Host: ' +host
                                            print conn.retrlines('LIST')
                                    except:
                                            print "Error in listing HOST "+host
                                            raise
                                    self.queue.task_done()
            finally:
                    self.lock.release()


  queue = Queue.Queue()

  for threads in range(5):
    worker = workerClass(queue,threads)
    worker.setDaemon(True)
    worker.start()
    threadsList.append(worker)
    print "Thread %d started  .."%threads

 for host in ftpSiteList:
    queue.put(host)

 queue.join()

 for threads in threadsList:
    threads.join()

 print "Scanning completed !!!"

=============================================== ============================

输出低于

Worker Thread 0 reporting for Service !!!
Thread 0 started  ..
Worker Thread 1 reporting for Service !!!
Thread 1 started  ..
Worker Thread 2 reporting for Service !!!
Thread 2 started  ..
Worker Thread 3 reporting for Service !!!
Thread 3 started  ..
Worker Thread 4 reporting for Service !!!
Thread 4 started  ..
Worker thread 4 exiting. 
Host: ftp4.FreeBSD.org
Host: ftp.crans.org
Host: ftp.ncsa.uiuc.edu
-rw-r--r--    1 ftp      ftp          5430 Jul 19  2014 favicon.ico
-rw-r--r--    1 ftp      ftp           655 Nov 24  2014 index.html
drwxr-xr-x    3 ftp      ftp             3 Jul 19  2014 pub
226 Directory send OK.
lrwxrwxrwx    1 0        0              10 Jun 14  2012 custom ->         pub/custom
lrwxrwxrwx    1 9865     9865           10 May 24  2012 debian ->    pub/debian
lrwxrwxrwx    1 9865     9865           20 May 27  2012 debian-backports -> pub/debian-backports
lrwxrwxrwx    1 9865     9865           22 May 24  2012 debian-multimedia -> pub/debian-multimedia/
lrwxrwxrwx    1 9865     9865           20 May 24  2012 debian-security -> pub/debian-security/
lrwxrwxrwx    1 0        0              10 Apr 14  2014 events -> pub/events
drwxrwsr-x   27 0        4            4096 Jan 27  2014 git
drwx------    2 9865     9865        16384 Jun 08  2012 lost+found
drwxr-xr-x   14 9865     9865         4096 Nov 26  2013 pub
lrwxrwxrwx    1 9865     9865           11 May 24  2012 ubuntu -> pub/ubuntu/
lrwxrwxrwx    1 0        0              12 Jun 14  2012 videolan ->   pub/videolan
226 Directory send OK.
Worker thread 1 exiting. 
-rw-r--r--    1 12873    floppy        784 Aug 22  1994 .index
-rw-r--r--    1 80       root          663 Jan  7  1995 .message
-rw-r--r--    1 80       root        25819 Dec 29  1994 Brochure
drwx------    2 80       ncsa         2048 Jun 16  1998 Cyberia
drwxr-xr-x    2 12873    root         2048 Aug 22  1994 DTM
drwxrwxrwx    4 root     root         2048 Dec  4  2003 Director
drwxr-xr-x   13 14453    root         2048 Aug 22  1994 Documentation
drwxr-xr-x    9 root     root         2048 Feb  5  1997 Education
drwxrwxrwx    2 root     root         2048 Apr  9  1996 FigLeaf
drwxr-xr-x   13 19099    root         2048 Aug 22  1994 GlobalModels
drwxr-xr-x    8 12873    root         2048 May 17  1996 Mac
drwxr-xr-x   10 12873    root         2048 Feb 15  2002 Mosaic
drwxr-xr-x    5 12873    root         2048 Jan  5  1995 PC
-rw-r--r--    1 80       root        16557 Jan  3  1995 README
-rw-r--r--    1 12873    root         1933 Jan 12  1995 README.FIRST
drwxr-xr-x    5 12873    root         2048 Feb 15  2002 SGI
drwxr-xr-x    4 12873    root         2048 Dec 20  1994 Telnet
drwxr-xr-x    7 12873    root         2048 Aug 24  1994 Unix
drwxrwxrwx   12 root     root         2048 Jan 30  2004 VR
drwxr-xr-x   24 12873    root         2048 May 31  1997 Visualization
drwxrwxrwx    2 root     root         2048 May 20  1996 Vosaic
drwxr-xr-x    6 12873    root         2048 May 16  1997 Web
drwxrwxrwx   24 root     root         2048 Sep 22  2006 aces
drwxr-xr-x   10 12873    root         2048 Aug 22  1994 aff
drwxrwxrwx    2 root     root         2048 Jul 24  2002 aips
drwxrwxrwx   12 root     root        43008 Aug 27 00:30 alg
drwxrwxrwx    4 root     root         2048 Mar 17  2003 benchmarks
dr-xrwxrwx    2 root     root         2048 Apr 21  2006 bin
drw-r--r--    2 15332    wheel        2048 Jan 27  1999 chemistry
drwxrwxrwx   68 root     root         4096 Apr 12  2007 cosmic
drwx------    3 80       ncsa         2048 May 24  2002 dbalsara
drwx------    2 80       games        2048 Dec 23  1997 emerge
drwxr-xr-x    3 80       root         2048 Jun 27  2006 etc
drwxr-xr-x    4 80       sys          2048 May 12  2009 incoming
drwx------    3 80       games        2048 Aug 25  1997 java
drwx------    2 80       games        2048 Jul 22  1997 joule
drwx------    7 80       ncsa         2048 Jun  5  2000 lca
drwxrwxrwx    2 root     root         2048 Nov  9  2001 lib
drwxrwxrwx   16 root     root         2048 Sep 25  2003 media
drwxr-xr-x   14 12873    root         2048 Nov 21  2001 misc
drwxrwxrwx   21 root     root         2048 Mar 16  2001 ncsapubs
drwxrwxrwx   14 root     root         2048 Oct  3  2007 netdev
drwxrwxr-x   31 12984    wheel        2048 Mar 19  2015 outgoing
drwxr-xr-x    4 12873    root         2048 Dec 21  1999 sc22wg5
drwx------    2 nobody   games        2048 Mar 15  2007 security
drwxr-xr-x    2 root     root         2048 Dec 22  1999 x3j3
Worker thread 3 exiting. 
226 Transfer complete.
Worker thread 2 exiting. 
Host: ftp.x.org
-rw-r--r--   2 ftp      ftp           479 Nov  6  2001 banner2
lrwxrwxrwx   1 ftp      ftp             7 Oct  9  2005 bin -> usr/bin
drwxr-xr-x  34 ftp      ftp          4096 Nov  6  2001 contrib
d--x--x--x   2 ftp      ftp          4096 Aug  8  2001 dev
drwxr-xr-x   2 ftp      ftp          4096 Oct 12  1998 digest
d--x--x--x   3 ftp      ftp          4096 Aug  8  2001 etc
-rw-r--r--   1 ftp      ftp          3075 Oct  7  1998 GettingBroadway
-rw-r--r--   1 ftp      ftp          3075 Oct  7  1998 GettingR6.3
-rw-r--r--   1 ftp      ftp          1847 Feb  1  1999 GettingR6.4
-rw-r--r--   1 ftp      ftp          1378 Aug 24  2000 GettingR6.5.1
-rw-r--r--   1 ftp      ftp          1229 Apr 24  2001 GettingR6.6
-rw-r--r--   1 ftp      ftp           301 Dec 22  2005 GettingR6.7
-rw-r--r--   1 ftp      ftp           396 Dec 22  2005 GettingR6.8
-rw-r--r--   1 ftp      ftp           396 Dec 22  2005 GettingR6.9
-rw-r--r--   1 ftp      ftp           396 Dec 22  2005 GettingR7.0
-rw-r--r--   1 ftp      ftp           195 Dec 30  2004 MIRROR.README
drwxrwxr-x  36 ftp      ftp          4096 Jun 30  2013 pub
drwxr-xr-x  56 ftp      ftp         24576 May  4  2001 R5contrib
drwxr-xr-x   2 ftp      ftp          4096 May  4  2001 rcsfaq
-r--r--r--   1 ftp      ftp          1571 Dec 22  2005 README
lrwxrwxrwx   1 ftp      ftp             6 Nov 27  2005 README.txt ->      README
d--x--x--x   5 ftp      ftp          4096 Aug  8  2001 usr
-rw-r--r--   2 ftp      ftp           479 Nov  6  2001 welcome.msg
226 Transfer complete
Worker thread 0 exiting. 
Scanning complete !!!

2 个答案:

答案 0 :(得分:1)

那是因为你的lock变量是一个实例变量,而不是你希望它在你的线程之间共享的变量。

您在编写

时将变量定义为实例变量
def __init__(self, queue, tid):
    ...    
    self.lock = thread.Lock()
    ...

您可以通过

进行检查
def __init__(self,queue,tid):
        threading.Thread.__init__(self)
        self.queue = queue
        self.tid = tid
        print "%d !!!"% id(self.lock) # all threads print different ids

对于每个线程,这会给出不同的id,这意味着它们是独立的对象。

你想要的是创建一个类变量。类变量在类的所有实例中共享。

class workerClass(threading.Thread):
    lock = threading.Lock()
    def __init__(self,queue,tid):
        threading.Thread.__init__(self)
        self.queue = queue
        self.tid = tid

    def run(self):
        lock.acquire()
        # do stuff
        lock.release()

答案 1 :(得分:0)

#!/usr/bin/python
import threading
import Queue
from ftplib import FTP

ftpSiteList = [ 'ftp.x.org', 'ftp4.FreeBSD.org',    'ftp.ncsa.uiuc.edu','ftp.crans.org' ]
threadsList = []


class workerClass(threading.Thread):
    lock = threading.Lock()

    def __init__(self,queue,tid):
        threading.Thread.__init__(self)
    self.queue = queue
    self.tid = tid
    print "Worker Thread %d reporting for Service with the lock id %d!!!"%(self.tid,id(workerClass.lock))

def run(self):
    try:
        workerClass.lock.acquire()
        while True:


            host = ''
            try:
                host = self.queue.get(timeout=1)
            except Queue.Empty:
                print "Worker thread %d exiting. "%(self.tid)
                return
            try:
                conn = FTP(host)
                conn.login()
                print 'Host: ' +host
                print conn.retrlines('LIST')
            except:
                print "Error in listing HOST "+host
                raise

            self.queue.task_done()

    finally:

        workerClass.lock.release()
queue = Queue.Queue()

for threads in range(5):
    worker = workerClass(queue,threads)
    worker.setDaemon(True)
    worker.start()
    threadsList.append(worker)
    print "Thread %d started  .."%threads

for host in ftpSiteList:
    queue.put(host)

queue.join()

for threads in threadsList:
    threads.join()

print "Scanning completed !!!"