简体   繁体   English

Python最简单的多处理形式

[英]Python simplest form of multiprocessing

Ive been trying to read up on threading and multiprocessing but all the examples are to intricate and advanced for my level of python/programming knowlegde. 我一直在尝试阅读有关线程和多处理的内容,但是所有示例对于我的python /编程Knowledgelegde的级别都是复杂的和高级的。 I want to run a function, which consists of a while loop, and while that loop runs I want to continue with the program and eventually change the condition for the while-loop and end that process. 我想运行一个由while循环组成的函数,当该循环运行时,我想继续执行程序并最终更改while循环的条件并结束该过程。 This is the code: 这是代码:

class Example():

    def __init__(self):
        self.condition = False

    def func1(self):
        self.condition = True
        while self.condition:
            print "Still looping"
            time.sleep(1)
        print "Finished loop"

    def end_loop(self):
        self.condition = False

The I make the following function-calls: 我进行以下函数调用:

ex = Example()
ex.func1()
time.sleep(5)
ex.end_loop()

What I want is for the func1 to run for 5s before the end_loop() is called and changes the condition and ends the loop and thus also the function. 我想要的是func1在end_loop()之前先运行5 end_loop()然后更改条件并结束循环以及函数。 Ie I want one process to start and "go" into func1 and at the same time I want time.sleep(5) to be called, so the processes "split" when arriving at func1 , one process entering the function while the other continues down the program and start with the time.sleep(5) execution. 也就是说,我希望一个进程启动并“进入” func1 ,同时我希望time.sleep(5) ,因此到达func1时进程“分裂”,一个进程进入函数,而另一个进程继续向下执行程序并从time.sleep(5)执行开始。

This must be the most basic example of a multiprocess, still Ive had trouble finding a simple way to do it! 这肯定是多进程的最基本示例,但我仍然很难找到一种简单的方法!

Thank you 谢谢

EDIT1: regarding do_something . EDIT1:关于do_something In my real problem do_something is replaced by some code that communicates with another program via a socket and receives packages with coordinates every 0.02s and stores them in membervariables of the class. 在我真正的问题中, do_something被替换为一些代码,这些代码通过套接字与另一个程序通信,并接收坐标为每0.02s的包并将它们存储在该类的membervariables中。 I want this constant updating of the coordinates to start and then be able to to read the coordinates via other functions at the same time. 我希望开始不断进行坐标更新,然后可以同时通过其他功能读取坐标。

However that is not so relevant. 但是,这并不重要。 What if do_something is replaced by: 如果将do_something替换为:

time.sleep(1)
print "Still looping"

How do I solve my problem then? 那我该如何解决我的问题呢?

EDIT2: I have tried multiprocessing like this: EDIT2:我尝试过这样的多处理:

from multiprocessing import Process
ex = Example()    
p1 = Process(target=ex.func1())
p2 = Process(target=ex.end_loop())

p1.start()
time.sleep(5)
p2.start()

When I ran this, I never got to p2.start() , so that did not help. 当我运行它时,我从没有p2.start() ,所以那无济于事。 Even if it had this is not really what Im looking for either. 即使它不是我要找的东西。 What I want would be just to start the process p1 , and then continue with time.sleep and ex.end_loop() 我要的是刚刚启动进程p1 ,然后继续time.sleepex.end_loop()

The first problem with your code are the calls 您的代码的第一个问题是调用

p1 = Process(target=ex.func1())
p2 = Process(target=ex.end_loop())

With ex.func1() you're calling the function and pass the return value as target parameter. 使用ex.func1()可以调用函数并将返回值作为target参数传递。 Since the function doesn't return anything, you're effectively calling 由于该函数不返回任何内容,因此您可以有效地调用

p1 = Process(target=None)
p2 = Process(target=None)

which makes, of course, no sense. 当然,这毫无意义。

After fixing that, the next problem will be shared data : when using the multiprocessing package, you implement concurrency using multiple processes which, by default, cannot simply share data afaik. 解决此问题后,下一个问题将是共享数据 :使用multiprocessing程序包时,您将使用多个进程实现并发,这些进程默认情况下不能简单地共享数据afaik。 Have a look at Sharing state between processes in the package's documentation to read about this. 请参阅软件包文档中的进程之间的共享状态以了解此内容。 Especially take the first sentence into account: "when doing concurrent programming it is usually best to avoid using shared state as far as possible"! 尤其要考虑到第一句话:“在进行并行编程时,通常最好尽可能避免使用共享状态”!

So you might want to also have a look at Exchanging objects between processes to read about how to send/receive data between two different processes. 因此,您可能还想看看在进程之间交换对象,以了解如何在两个不同的进程之间发送/接收数据。 So, instead of simply setting a flag to stop the loop, it might be better to send a message to signal the loop should be terminated. 因此,与其简单地设置一个标志来停止循环,不如发送一条消息来表明该循环应该终止,这可能更好。

Also note that processes are a heavyweight form of multiprocessing, they spawn multiple OS processes which comes with a relatively big overhead. 还应注意,进程是多重处理的重量级形式,它们产生多个OS进程,而这些进程具有相对较大的开销。 multiprocessing 's main purpose is to avoid problems imposed by Python's Global Interpreter Lock (google about this to read more...) If your problem is'nt much more complex than what you've told us, you might want to use the threading package instead: threads come with less overhead than processes and also allow to access the same data (although you really should read about synchronization when doing this...) multiprocessing的主要目的是避免Python的Global Interpreter Lock (有关此内容的更多信息,请参阅google。)引起的问题。如果您的问题并不比您告诉我们的问题复杂得多,则可能需要使用threading而是使用包:线程比进程具有更少的开销,并且还允许访问相同的数据(尽管在执行此操作时您确实应该了解同步 ...)

I'm afraid, multiprocessing is an inherently complex subject. 恐怕,多处理是一个固有的复杂主题。 So I think you will need to advance your programming/python skills to successfully use it. 因此,我认为您需要提高编程/ python技能才能成功使用它。 But I'm sure you'll manage this, the python documentation about this is comprehensive and there are a lot of other resources about this. 但是我敢肯定,您将对此进行管理,有关此问题的python文档非常全面,并且还有很多其他资源。

To tackle your EDIT2 problem, you could try using the shared memory map Value . 要解决您的EDIT2问题,您可以尝试使用共享内存映射Value

import time
from multiprocessing import Process, Value

class Example():

  def func1(self, cond):
    while (cond.value == 1):
      print('do something')
      time.sleep(1)
    return

if __name__ == '__main__':

  ex = Example()
  cond = Value('i', 1)
  proc = Process(target=ex.func1, args=(cond,))

  proc.start()
  time.sleep(5)
  cond.value = 0
  proc.join()

(Note the target=ex.func1 without the parentheses and the comma after cond in args=(cond,) .) (请注意, args=(cond,)后没有括号和逗号的target=ex.func1 。)

But look at the answer provided by MartinStettner to find a good solution. 但是请看一下MartinStettner提供的答案,以找到一个好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM