Python 如何使用。加入此过程
您好,我正在创建这个worker generator类,我在terminate上遇到挂起问题。我知道我需要使用Python 如何使用。加入此过程,python,join,process,freeze,Python,Join,Process,Freeze,您好,我正在创建这个worker generator类,我在terminate上遇到挂起问题。我知道我需要使用.join关闭它们,但我不知道如何将进程名称传递给terminate函数。我的想法是把它保存到一个全局变量,我在想一本字典。然后,当需要终止工作人员时,在消息队列中滴下毒药后,请访问该函数变量并终止适用的进程 class worker_manager: i = test_imports() #someVarForP #someVarForP2
.join
关闭它们,但我不知道如何将进程名称传递给terminate
函数。我的想法是把它保存到一个全局变量,我在想一本字典。然后,当需要终止工作人员时,在消息队列中滴下毒药后,请访问该函数变量并终止适用的进程
class worker_manager:
i = test_imports()
#someVarForP
#someVarForP2
def generate(control_queue, threadName, runNum):
if threadName == 'one':
print ("Starting import_1 number %d") % runNum
p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum))
#someVarForP = p
p.start()
if threadName == 'two':
print ("Starting import_2 number %d") % runNum
p = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum))
#someVarForP2 = p2
p.start()
if threadName == 'three':
p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum))
print ("Starting import_1 number %d") % runNum
p2 = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum))
print ("Starting import_2 number %d") % runNum
#someVarForP = p
#someVarForP2 = p2
p.start()
p2.start()
def terminate(threadName):
if threadName == 'one':
#self.someVarForP.join()
if threadName == 'two':
#self.someFarForP2.join()
if threadName == 'three':
#self.someVarForP.join()
#self.someVarForP2.join()
如果你们有任何想法,我将不胜感激,我不会停留在任何具体的方式来做这件事,我是一种新的python,所以任何建议都欢迎
编辑:完整的代码
import multiprocessing
import time
class test_imports:#Test classes remove
def import_1(self, control_queue, thread_number):
print ("Import_1 number %d started") % thread_number
run = True
count = 1
while run:
alive = control_queue.get()
if alive == 't1kill':
print ("Killing thread type 1 number %d") % thread_number
run = False
break
print ("Thread type 1 number %d run count %d") % (thread_number, count)
count = count + 1
def import_2(self, control_queue, thread_number):
print ("Import_1 number %d started") % thread_number
run = True
count = 1
while run:
alive = control_queue.get()
if alive == 't2kill':
print ("Killing thread type 2 number %d") % thread_number
run = False
break
print ("Thread type 2 number %d run count %d") % (thread_number, count)
count = count + 1
class worker_manager:
# ...
names = {'one': 'import_1', 'two': 'import_2'}
def __init__(self):
self.children = {}
def generate(self, control_queue, threadName, runNum):
name = self.names[threadName]
target = i.getattr(name)
print ("Starting %s number %d") % (name, runNum)
p = multiprocessing.Process(target=target, args=(control_queue, runNum))
self.children[threadName] = p
p.start()
def terminate(self, threadName):
self.children[threadName].join()
if __name__ == '__main__':
# Establish communication queues
control = multiprocessing.Queue()
manager = worker_manager()
runNum = int(raw_input("Enter a number: "))
threadNum = int(raw_input("Enter number of threads: "))
threadName = raw_input("Enter number: ")
thread_Count = 0
print ("Starting threads")
for i in range(threadNum):
if threadName == 'three':
manager.generate(control, 'one', i)
manager.generate(control, 'two', i)
manager.generate(control, threadName, i)
thread_Count = thread_Count + 1
if threadName == 'three':
thread_Count = thread_Count + 1
time.sleep(runNum)#let threads do their thing
print ("Terminating threads")
for i in range(thread_Count):
control.put("t1kill")
control.put("t2kill")
if threadName == 'three':
manager.terminate('one')
manager.terminate('two')
else:
manager.terminate(threadName)
仅编辑
worker\u manager
是其中唯一实际使用的部分。剩下的只是开发它,只是一个提示 首先,如果从名为terminate
的函数使用join
,我不确定您是否了解它的功能。调用join
时,所做的只是让父进程等待子进程完成。您仍然需要告诉子进程它需要完成(例如,通过在队列中为它发布某些内容,或向它发送信号),否则您将永远等待
其次,您将self
参数从方法中删除,使用了一个旧式的类,创建了一个类属性,您可能需要一个实例属性,并开始讨论全局变量,因为它似乎非常适合实例属性,这意味着您可能对类也有一些误解
但最大的问题似乎是您希望将字符串名称映射到实例属性(或其他类型的变量)。虽然您可以这样做。不要为每个名称使用单独的属性,只需使用一个带有每个名称值的dict
。例如:
class worker_manager:
# ...
def __init__(self):
self.children = {}
def generate(self, control_queue, threadName, runNum):
if threadName == 'one':
print ("Starting import_1 number %d") % runNum
p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum))
self.children[threadName]
p.start()
# ...
def terminate(self, threadName):
self.children[threadName].join()
您可以通过分解if
块的公共部分来进一步清理这个问题。例如,您可能需要一个调度表。同时,我们还可以使用更多的标准名称、4个字符的缩进而不是random、一个新样式的类,等等:
class WorkerManager(object):
# ...
names = {'one': 'import_1', 'two': 'import_2', 'three': 'import_3'}
def __init__(self):
self.children = {}
def generate(self, control_queue, threadName, runNum):
name = WorkerManager.names[threadName]
target = i.getattr(name)
print ("Starting %s number %d") % (name, runNum)
p = multiprocessing.Process(target=target, args=(control_queue, runNum))
self.children[threadName] = p
p.start()
def terminate(self, threadName):
self.children[threadName].join()
如果我们能看到更多的代码,可能还有很多东西需要重构,但这应该足以让您开始学习。是的,我还在学习python,我正在通过网络教程自学。我试图运行它,但我一直得到这个错误NameError:全局名称'names'没有定义我在你的字典后面添加了一个分号,就像我在源代码示例中所做的那样:names={'one':'import_1','two':'import_2','three':'import_3'};在通话中是self.names[threadName]非常感谢!首先,在Python中,行的末尾绝对不应该有分号。如果您是通过以下教程自学的,那么您需要找到更好的教程(也许您应该在此处发布链接,以便其他人知道如何引导人们远离这些教程……)。我仍然收到此错误AttributeError:'int'对象没有属性'getattr'。我添加了我的其余代码大部分只是为了开发worker_managerclass@KyleSponable:您的示例意味着
i
是一种对象,其方法名为import\u 1
,等等。我的回答假设了同样的情况。如果i
是一个int,那么它显然不起作用。我猜你的i
是一个全局变量,你已经在某个地方用覆盖了它,范围为(10)
或类似的值。这是您希望尽可能使用局部变量和实例属性的许多原因之一,并且为所有非平凡的事物提供好的名称。