Ask*_*man 7 python multithreading python-multithreading python-3.x
我有这个非常简单的python代码:
Test = 1;
def para():
while(True):
if Test > 10:
print("Test is bigger than ten");
time.sleep(1);
para(); # I want this to start in parallel, so that the code below keeps executing without waiting for this function to finish
while(True):
Test = random.randint(1,42);
time.sleep(1);
if Test == 42:
break;
...#stop the parallel execution of the para() here (kill it)
..some other code here
Run Code Online (Sandbox Code Playgroud)
基本上,我想要将函数para()与其他代码并行运行,以便它下面的代码不必等待para()结束.但是,我希望能够在并行运行时访问para()内部的Test变量的当前值(如上面的代码示例所示).后来,当我决定,我完成了并行运行的para()时,我想知道如何从主线程中杀死它,还要从并行运行的para()本身(自我 - 终止).
我已经阅读了一些关于线程的教程,但是几乎每个教程都以不同的方式处理它,而且我很难理解其中的一些,所以我想知道,并行运行一段代码的最简单方法是什么.
谢谢.
好的,首先,这是对您的问题的逐字答案,以最简单的方式。之后,我们用两个示例更全面地回答,这两个示例展示了执行此操作以及在主代码和并行代码之间共享数据访问的两种方法。
import random
from threading import Thread
import time
Test = 1;
stop = False
def para():
while not stop:
if Test > 10:
print("Test is bigger than ten");
time.sleep(1);
# I want this to start in parallel, so that the code below keeps executing without waiting for this function to finish
thread = Thread(target=para)
thread.start()
while(True):
Test = random.randint(1,42);
time.sleep(1);
if Test == 42:
break;
#stop the parallel execution of the para() here (kill it)
stop = True
thread.join()
#..some other code here
print( 'we have stopped' )
Run Code Online (Sandbox Code Playgroud)
现在,更完整的答案:
下面我们将展示两个代码示例(如下所列),演示 (a) 使用线程接口并行执行,以及 (b) 使用多处理接口。您选择使用其中哪一个取决于您想要做什么。当第二个线程的目的是等待 I/O 时,线程可能是一个不错的选择,而当第二个线程用于执行 CPU 密集型计算时,多处理可能是一个不错的选择。
在您的示例中,主代码更改了变量,并行代码仅检查该变量。如果您想更改两者的变量(例如重置共享计数器),情况就会有所不同。因此,我们也将向您展示如何做到这一点。
在下面的示例代码中:
变量“ counter ”、“ run ”和“ lock ”在主程序和并行执行的代码之间共享。
函数myfunc()是并行执行的。它循环更新计数器并休眠,直到主程序将run设置为 false。
主程序循环打印计数器的值,直到达到 5,此时它重置计数器。然后,当它再次达到 5 后,它将run设置为 false,最后,它等待线程或进程退出,然后再退出。
您可能会注意到,计数器在第一个示例中调用lock.acquire()和lock.release()时递增,或者在第二个示例中使用lock时递增。
递增计数器包括三个步骤:(1) 读取当前值,(2) 加一,然后 (3) 将结果存储回计数器。当一个线程尝试在发生这种情况的同时设置计数器时,就会出现问题。
我们通过让主程序和并行代码在更改变量之前获取锁,然后在完成后释放它来解决这个问题。如果锁已被占用,则程序或并行代码将等待直到锁被释放。这会同步他们对更改共享数据(即计数器)的访问。(另外,请参阅信号量以了解另一种同步)。
通过上述介绍,这是第一个示例,它使用线程:
# Parallel code with shared variables, using threads
from threading import Lock, Thread
from time import sleep
# Variables to be shared across threads
counter = 0
run = True
lock = Lock()
# Function to be executed in parallel
def myfunc():
# Declare shared variables
global run
global counter
global lock
# Processing to be done until told to exit
while run:
sleep( 1 )
# Increment the counter
lock.acquire()
counter = counter + 1
lock.release()
# Set the counter to show that we exited
lock.acquire()
counter = -1
lock.release()
print( 'thread exit' )
# ----------------------------
# Launch the parallel function as a thread
thread = Thread(target=myfunc)
thread.start()
# Read and print the counter
while counter < 5:
print( counter )
sleep( 1 )
# Change the counter
lock.acquire()
counter = 0
lock.release()
# Read and print the counter
while counter < 5:
print( counter )
sleep( 1 )
# Tell the thread to exit and wait for it to exit
run = False
thread.join()
# Confirm that the thread set the counter on exit
print( counter )
Run Code Online (Sandbox Code Playgroud)
这是第二个示例,它使用多处理。请注意,访问共享变量涉及一些额外的步骤。
from time import sleep
from multiprocessing import Process, Value, Lock
def myfunc(counter, lock, run):
while run.value:
sleep(1)
with lock:
counter.value += 1
print( "thread %d"%counter.value )
with lock:
counter.value = -1
print( "thread exit %d"%counter.value )
# =======================
counter = Value('i', 0)
run = Value('b', True)
lock = Lock()
p = Process(target=myfunc, args=(counter, lock, run))
p.start()
while counter.value < 5:
print( "main %d"%counter.value )
sleep(1)
with lock:
counter.value = 0
while counter.value < 5:
print( "main %d"%counter.value )
sleep(1)
run.value = False
p.join()
print( "main exit %d"%counter.value)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1951 次 |
| 最近记录: |