Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用。加入此过程_Python_Join_Process_Freeze - Fatal编程技术网

Python 如何使用。加入此过程

Python 如何使用。加入此过程,python,join,process,freeze,Python,Join,Process,Freeze,您好,我正在创建这个worker generator类,我在terminate上遇到挂起问题。我知道我需要使用.join关闭它们,但我不知道如何将进程名称传递给terminate函数。我的想法是把它保存到一个全局变量,我在想一本字典。然后,当需要终止工作人员时,在消息队列中滴下毒药后,请访问该函数变量并终止适用的进程 class worker_manager: i = test_imports() #someVarForP #someVarForP2

您好,我正在创建这个worker generator类,我在terminate上遇到挂起问题。我知道我需要使用
.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)
或类似的值。这是您希望尽可能使用局部变量和实例属性的许多原因之一,并且为所有非平凡的事物提供好的名称。