【问题标题】:Make 2 functions run at the same time使 2 个函数同时运行
【发布时间】:2011-02-26 18:41:39
【问题描述】:

我正在尝试让 2 个函数同时运行。

def func1():
    print 'Working'

def func2():
    print 'Working'

func1()
func2()

有人知道怎么做吗?

【问题讨论】:

标签: python multithreading parallel-processing


【解决方案1】:

这样做:

from threading import Thread

def func1():
    print('Working')

def func2():
    print("Working")

if __name__ == '__main__':
    Thread(target = func1).start()
    Thread(target = func2).start()

【讨论】:

  • 他可能想知道,由于全局解释器锁,即使所讨论的机器有多个 CPU,它们也不会在完全相同的时间执行。 wiki.python.org/moin/GlobalInterpreterLock
  • @joaquin -- 对了,抱歉,复制粘贴后忘记取出函数执行了。
  • 函数返回时如何获取结果?
  • 没有理由使用两个导入语句。只需使用第二个。
  • 如何为函数提供参数?
【解决方案2】:

The answer about threading 很好,但你需要更具体地说明你想做什么。

如果您有两个都使用大量 CPU 的函数,那么线程(在 CPython 中)可能会让您一事无成。然后你可能想看看multiprocessing module 或者你可能想使用jython/IronPython。

如果 CPU 受限的性能是原因,您甚至可以在(非线程)C 中实现,并获得比在 python 中执行两个并行操作更大的加速。

没有更多的信息,很难想出一个好的答案。

【讨论】:

    【解决方案3】:

    一个选项,看起来它可以让两个函数同时运行
    时间
    ,正在使用threading 模块(this 答案中的示例)。

    但是,正如官方 Python 文档
    page 所述,它有一点延迟。可以尝试使用的更好的模块是 multiprocessing

    此外,还有其他 Python 模块可用于异步执行(两段代码同时工作)。有关它们的一些信息和帮助选择一个,您可以阅读this Stack Overflow 问题。

    其他用户对threading 模块的评论

    由于全局解释器锁定,他可能想知道这一点
    即使机器在
    中,它们也不会同时执行 问题有多个 CPU。 wiki.python.org/moin/GlobalInterpreterLock

    – 乔纳斯·埃尔夫斯特罗姆 Jun 2 '10 at 11:39

    引用文档中关于 threading 模块不工作的内容

    CPython 实现细节:在 CPython 中,由于 Global Interpreter
    锁,一次只能有一个线程执行 Python 代码(尽管
    某些面向性能的库可能会克服这个限制)。

    如果您希望您的应用程序更好地利用多核机器的计算资源,建议您使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。
    但是,如果您
    ,线程仍然是一个合适的模型 想要同时运行多个 I/O 密集型任务。

    【讨论】:

    • 我在每个 print() 函数的末尾附加 time.time() 并将循环限制为另一个答案的代码的 9 次。这是我在终端中所看到的:('a',1509314761.857559)('a',1509314761.857664)('a',1509314761.85767)('a',1509314761.857675)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768)('a',1509314761.85768 )('a',1509314761.85769)('a',1509314761.857695)('a',1509314761.857699)('b',1509314761.858138)('b',1509314761.858224)('b',1509314761.858229)('b',1509314761.858229) ('b', 1509314761.858239) ('b', 1509314761.858244) ('b', 1509314761.858249) ('b', 1509314761.858253) ('b', 1509314761.858258)
    • 即使使用多处理,也不是真正的并发仪式?一个接一个地跑。
    • @weefwefwqg3 检查我对模块详细信息的回答中的链接。您也可以自己检查,但官方文档应该解释。
    • Idk 如果它是一个错误,但对我来说,多处理不起作用。 thr1 = Process(target=run_foo(), args=()) 行不应该创建线程(因为我没有运行thr1.start() 实际上创建了它,因此应该由@987654334 启动的进程@窃取执行,所以没有多线程。
    【解决方案4】:

    试试这个

    from threading import Thread
    
    def fun1():
        print("Working1")
    def fun2():
        print("Working2")
    
    t1 = Thread(target=fun1)
    t2 = Thread(target=fun2)
    
    t1.start()
    t2.start()
    

    【讨论】:

    • 添加对如何解决 OP 要求的见解
    • 我怎样才能用return语句做到这一点,它只有在函数有打印时才有效
    【解决方案5】:

    与多进程不同,线程模块确实同时工作,但时间有点不对。下面的代码打印一个“1”和一个“2”。它们分别由不同的函数调用。我确实注意到,当打印到控制台时,它们的时间会略有不同。

    from threading import Thread
    
    def one():
        while(1 == num):
            print("1")
            time.sleep(2)
        
    def two():
        while(1 == num):
            print("2")
            time.sleep(2)
    
    
    p1 = Thread(target = one)
    p2 = Thread(target = two)
    
    p1.start()
    p2.start()
    

    输出:(注意空格是打印之间的等待)

    1
    2
    
    2
    1
    
    12
       
    21
    
    12
       
    1
    2
    

    不确定是否有办法纠正这个问题,或者它是否重要。只是我注意到了。

    【讨论】:

      【解决方案6】:

      我认为您试图传达的内容可以通过多处理来实现。但是,如果您想通过线程执行此操作,则可以执行此操作。 这可能会有所帮助

      from threading import Thread
      import time
      
      def func1():
          print 'Working'
          time.sleep(2)
      
      def func2():
          print 'Working'
          time.sleep(2)
      
      th = Thread(target=func1)
      th.start()
      th1=Thread(target=func2)
      th1.start()
      

      【讨论】:

        【解决方案7】:

        这可以通过Ray 优雅地完成,该系统可让您轻松并行化和分发 Python 代码。

        要并行化您的示例,您需要使用@ray.remote decorator 定义您的函数,然后使用.remote 调用它们。

        import ray
        
        ray.init()
        
        # Define functions you want to execute in parallel using 
        # the ray.remote decorator.
        @ray.remote
        def func1():
            print("Working")
        
        @ray.remote
        def func2():
            print("Working")
        
        # Execute func1 and func2 in parallel.
        ray.get([func1.remote(), func2.remote()])
        

        如果func1()func2() 返回结果,则需要稍微重写上面的代码,将ray.get([func1.remote(), func2.remote()]) 替换为:

        ret_id1 = func1.remote()
        ret_id2 = func1.remote()
        ret1, ret2 = ray.get([ret_id1, ret_id2])
        

        multiprocessing 模块相比,使用Ray 或使用多线程有许多优点。特别是,相同的代码可以在单台机器上运行,也可以在一组机器上运行。

        有关 Ray 的更多优势,请参阅this related post

        【讨论】:

          【解决方案8】:

          使用 APscheduler 进行测试:

          from apscheduler.schedulers.background import BackgroundScheduler
          import datetime
          
          dt = datetime.datetime
          Future = dt.now() + datetime.timedelta(milliseconds=2550)  # 2.55 seconds from now testing start accuracy
          
          def myjob1():
              print('started job 1: ' + str(dt.now())[:-3])  # timed to millisecond because thats where it varies
              time.sleep(5)
              print('job 1 half at: ' + str(dt.now())[:-3])
              time.sleep(5)
              print('job 1 done at: ' + str(dt.now())[:-3])
          def myjob2():
              print('started job 2: ' + str(dt.now())[:-3])
              time.sleep(5)
              print('job 2 half at: ' + str(dt.now())[:-3])
              time.sleep(5)
              print('job 2 done at: ' + str(dt.now())[:-3])
          
          print(' current time: ' + str(dt.now())[:-3])
          print('  do job 1 at: ' + str(Future)[:-3] + ''' 
            do job 2 at: ''' + str(Future)[:-3])
          sched.add_job(myjob1, 'date', run_date=Future)
          sched.add_job(myjob2, 'date', run_date=Future)
          

          我得到了这些结果。这证明它们是同时运行的。

           current time: 2020-12-15 01:54:26.526
            do job 1 at: 2020-12-15 01:54:29.072  # i figure these both say .072 because its 1 line of print code
            do job 2 at: 2020-12-15 01:54:29.072
          started job 2: 2020-12-15 01:54:29.075  # notice job 2 started before job 1, but code calls job 1 first.
          started job 1: 2020-12-15 01:54:29.076  
          job 2 half at: 2020-12-15 01:54:34.077  # halfway point on each job completed same time accurate to the millisecond
          job 1 half at: 2020-12-15 01:54:34.077
          job 1 done at: 2020-12-15 01:54:39.078  # job 1 finished first. making it .004 seconds faster.
          job 2 done at: 2020-12-15 01:54:39.091  # job 2 was .002 seconds faster the second test
          

          【讨论】:

            【解决方案9】:

            如果您还想等待直到两个功能都完成:

            from threading import Thread
            
            def func1():
                print 'Working'
            
            def func2():
                print 'Working'
            
            # Define the threads and put them in an array
            threads = [
                Thread(target = self.func1),
                Thread(target = self.func2)
            ]
            
            # Func1 and Func2 run in separate threads
            for thread in threads:
                thread.start()
            
            # Wait until both Func1 and Func2 have finished
            for thread in threads:
                thread.join()
            

            【讨论】:

              猜你喜欢
              • 2015-09-19
              • 2012-09-04
              • 2015-07-26
              • 1970-01-01
              • 2017-07-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多