python 线程就像一个进程, 甚至可能是一个进程, 这取决于 python 线程系统。事实上, python 线程有时被称为 “轻量级” 进程, 因为线程占用的内存比创建进程所需的时间少得多。
线程允许应用程序一次执行多个任务。多线程在许多应用中都很重要。
在 python 中, 线程模块用于创建线程。为了创建线程, 线程模块可以通过两种方式使用。首先, 通过继承类, 第二通过使用线程函数。
使用类创建 python 线程
让我们通过使用代码来理解。
import threading
class mythread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.h = i
def run(self):
print“ Value send“, self.h
thread1 = mythread(1)
thread1.start()
- 新类 < c/> 继承 python < c/c/ > 类。
__init__(self [,args])
:重写构造函数。run()
: 这是您可以放置逻辑部分的部分。start()
: < c//> 方法启动 python 线程。- < c/> 类将覆盖构造函数, 因此必须调用基类构造函数 (< c2/>)。
使用函数创建 python 线程
import threading
def fun1(a, b):
c = a + b
print(c)
thread1 = threading.Thread(target = fun1, args = (12, 10))
thread1.start()
上面的代码很简单。只需创建一个函数, 并让它通过线程运行。的语法
threading.Thread(target=fun1, args=(12,10)) creates a thread, the target = fun1
指定要运行的函数, < cn/> 指示包含要传递给函数的参数的元组。
重要的线程方法
让我们看看一些在线程模块中定义的重要方法。
threading.activeCount()
: 返回活动的 python 线程总数。
让我们通过这个例子来理解。
让我们看看输出。
import threading
import time
def fun1(a, b):
time.sleep(1)
c = a + b
print(c)
thread1 = threading.Thread(target = fun1, args = (12, 10))
thread1.start()
thread2 = threading.Thread(target = fun1, args = (10, 17))
thread2.start()
print(“Total number of threads”, threading.activeCount())
print(“List of threads: “, threading.enumerate())
图 1: 所有线程和线程列表
现在注释出行 < cn/>, 然后再次运行代码。
图 2: 无睡眠时间
你可以看到其中的区别。语句 < cn /> 和 < c2/> 运行了主线或主线程。因此, 主线程负责运行整个程序活动计数 ()、线程1和线程2处于活动状态。
当我们注释掉 < cn/> 语法并再次执行代码时, 线程1和线程3可能不处于活动状态。
联接方法
在讨论 < c/a 方法的意义之前, 让我们先看看下面的程序。
在上面的程序中, 使用参数创建了这两个线程。在目标函数 < cn/> 中, 附加了一个全局列表 < cl >。让我们看看结果。
import threading
import time
list1 = []
def fun1(a):
time.sleep(1)# complex calculation takes 1 seconds
list1.append(a)
thread1 = threading.Thread(target = fun1, args = (1, ))
thread1.start()
thread2 = threading.Thread(target = fun1, args = (6, ))
thread2.start()
print(“List1 is: “, list1)
图 3: 显示空列表
上图显示的是空列表, 但该列表将使用值1和6填充。语句 < cn/> 由主线程执行, 主线程在填写列表之前打印列表。
因此, 必须暂停主线程, 直到所有线程完成其作业。为此, 我们将使用 < c/> 方法。
让我们来看看修改后的代码。
import threading
import time
list1 = []
def fun1(a):
time.sleep(1)# complex calculation takes 1 seconds
list1.append(a)
thread1 = threading.Thread(target = fun1, args = (1, ))
thread1.start()
thread2 = threading.Thread(target = fun1, args = (6, ))
thread2.start()
thread1.join()
thread2.join()
print(“List1 is: “, list1)
这里是一个输出。
图 4: < c/> 方法的使用
在上面的代码中, 语法 < c/> 会阻止主线程, 直到 < c2/> 完成其任务。为了实现并行性, 必须在创建所有线程后调用 < cn/> 方法。
让我们看看更多 < cn/ > 方法的用例。
import threading
import time
import datetime
t1 = datetime.datetime.now()
list1 = []
def fun1(a):
time.sleep(1)# complex calculation takes 1 seconds
list1.append(a)
list_thread = []
for each in range(10):
thread1 = threading.Thread(target = fun1, args = (each, ))
list_thread.append(thread1)
thread1.start()
for th in list_thread:
th.join()
print(“List1 is: “, list1)
t2 = datetime.datetime.now()
print(“Time taken”, t2 - t1)
在上面的代码中, 我们使用 for 循环来创建10个线程。每个线程都被追加到列表中, < cn/>。创建所有线程后, 我们使用了 < c/t ‘ method。让我们看看输出。
图 5: 带循环的 “cn/ ” 输出
执行所需的时间约为1秒如果在创建每个线程程序后使用 < cn/> 方法, 则需要10秒以上的时间。
有关详细说明, 请参阅下面的代码。
import threading
import time
import datetime
t1 = datetime.datetime.now()
list1 = []
def fun1(a):
time.sleep(1)# complex calculation takes 1 seconds
list1.append(a)
for each in range(10):
thread1 = threading.Thread(target = fun1, args = (each, ))
thread1.start()
thread1.join()
print(“List1 is: “, list1)
t2 = datetime.datetime.now()
print(“Time taken”, t2 - t1)
输出:
图 6: 使用 < c/> 方法的线程
从上面的输出中可以清楚地看出, 所花费的时间是10秒。这意味着没有实现并行性, 因为在创建第二个线程之前调用了第一个线程的 < cn/> 方法。
与时间联接 () 方法
让我们看一下下面的一段代码。
import threading
import time
def fun1(a):
time.sleep(3)# complex calculation takes 3 seconds
thread1 = threading.Thread(target = fun1, args = (1, ))
thread1.start()
thread1.join()
print(thread1.isAlive())
这里有几件事是新的。方法返回 ” 真” 或 “假”。如果线程当前处于活动状态, 则方法 返回 true; 否则, 它返回 false。
输出:
上面的输出显示线程处于非活动状态。
让我们做一个小小的改变–把 < c//> 改为 < c >。这告诉程序只将主线程阻塞2秒钟。
让我们看看输出:
在上述输出中, 线程仍处于活动状态, 因为 < cn/将阻塞主线程 2秒钟, 但线程用了3秒才能完成其任务。
线程。定时器 ()
此方法用于设置时间。让我们来理解语法。
threading.Timer(interval, function, args=[], kwargs={})
上述语法的含义是, 在指定的时间间隔后, 以秒为单位, 解释器将使用 < cn /> 和 < c2/> 执行该函数。