【问题标题】:python : multithreading : self as global variablepython:多线程:self作为全局变量
【发布时间】:2016-04-20 08:31:51
【问题描述】:

我对 python 的多线程有一些问题: 生成一个线程,它会获取一些参数,如线程名称、计数器等。在线程的“运行”部分中,它正在调用一些子函数(并且还有一些深度的子函数)但是,自变量(类)似乎不存在于子函数中:指的是 self.name显示一些错误(NameError: global name 'self' is not defined )。有没有办法在不(!!)参数化所有内容的情况下获得这些子函数中完整结构的内容(这将在深度 4 处变得很长......)。希望这个简短的例子能更好地解释它,在 sub1 第二个打印行尝试访问 self.counter

#!/usr/bin/python

import threading
import time

globalVar = 1;

def sub1  ( name ):
  global globalVar ;

  print str(globalVar) + " in der 1. subfunktion von " +str(name)
  print "teste self"  + str(self.counter) + " - " + globalVar + " " +str(name) ;
  globalVar += 1 ;
  time.sleep(1);
  sub2 (name) ;
  return None ;


class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name + " mit zaehler " + str(self.counter)
        sub1 (self.name);

threadLock = threading.Lock()
threads = [] ;

# Create new threads
count =0;
while count < 10 :
        count += 1;
        threadX = myThread(count, "Thread-" + str(count), count)
        threadX.start()
        threads.append(threadX)

for t in threads:
    t.join()
print "Exiting Main Thread"

感谢您的帮助

【问题讨论】:

  • 您是否尝试过在线程运行中传递整个对象self 而不是只传递一个属性self.namesub1(self)

标签: python multithreading global-variables


【解决方案1】:

为什么你不简单地传递self 而不是name

#!/usr/bin/python

import threading
import time

globalVar = 1;

def sub1  ( self ):
  global globalVar ;

  print str(globalVar) + " in der 1. subfunktion von " +str(self.name)
  print "teste self"  + str(self.counter) + " - " + str(globalVar) + " " +str(self.name) ;
  globalVar += 1 ;
  time.sleep(1);
  sub2 (self.name) ;
  return None ;


class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name + " mit zaehler " + str(self.counter)
        sub1 (self);

threadLock = threading.Lock()
threads = [] ;

# Create new threads
count =0;
while count < 10 :
        count += 1;
        threadX = myThread(count, "Thread-" + str(count), count)
        threadX.start()
        threads.append(threadX)

for t in threads:
    t.join()
print "Exiting Main Thread"

由于int 无法与string 连接,我在sub1 方法中将globalVar 替换为str(globalVar)

工作如下:

>>> ================================ RESTART ================================
>>> 
Starting Thread-1 mit zaehler 1
1 in der 1. subfunktion von Thread-1
teste self1 - 1 Thread-1
Starting Thread-2 mit zaehler 2
2 in der 1. subfunktion von Thread-2
teste self2 - 2 Thread-2Starting Thread-3 mit zaehler 3
 Starting Thread-5 mit zaehler 5
Starting Thread-6 mit zaehler 6Starting Thread-7 mit zaehler 7Starting Thread-4 mit zaehler 4Starting Thread-8 mit zaehler 8Starting Thread-9 mit zaehler 9
 3 in der 1. subfunktion von Thread-3




3 in der 1. subfunktion von Thread-5Starting Thread-10 mit zaehler 10
3 in der 1. subfunktion von Thread-63 in der 1. subfunktion von Thread-73 in der 1. subfunktion von Thread-9
teste self3 - 3 Thread-3
3 in der 1. subfunktion von Thread-43 in der 1. subfunktion von Thread-8


teste self5 - 3 Thread-5
teste self7 - 3 Thread-7

3 in der 1. subfunktion von Thread-10teste self6 - 3 Thread-6teste self9 - 3 Thread-9
teste self4 - 4 Thread-4
teste self8 - 5 Thread-8

teste self10 - 6 Thread-10


//+ A bunch of Sub2 is not defined errors ...

【讨论】:

    【解决方案2】:

    sub1 不是“子函数”。 Python 有“嵌套”函数,但这不是它的一个例子。 “sub1”的作用域完全不同,在你的类下看不到任何变量。

    如果你想访问类实例(self)变量和方法,你应该将“self”作为参数传递给sub1,而不是self.name,它只是字符串“Thread-#”

    def sub1(thread_instance):
        print thread_instance.name, thread_instance.threadID
    

    然后在你的“运行”方法中,用 self 调用它:

    def run(self):
        sub1(self)
    

    不要使用带线程的全局变量来存储来自线程的对象,因为当多个线程读取和写入该变量时,这肯定会导致头痛。

    另外,如果它们都是一个且相同的,那么为你的类设置一个 threadID 和 counter 参数有什么意义呢?此外,您的代码示例不完整且缺少代码,因此很难理解您试图通过此实现的目标以及您试图做什么。

    另外一点,你不需要在每行后面加上分号,这不是 C。我会先集中精力了解 Python 语言,并在使用线程之前先了解一些基础知识。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多