Python线程threading模块用法详解
Python线程是为了实现多任务而提出来的一种技术。在Python中,线程是通过threading
模块来实现的。本文将详细介绍threading
模块的用法,包括线程的创建、启动、停止等所有相关知识。
线程的创建
在使用threading
模块创建线程时,可以有两种方式:
1. 通过继承Thread
类
import threading
class MyThread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
print("Thread " + self.name + " running")
t1 = MyThread("t1")
t1.start()
2. 通过实例化Thread
类
import threading
def thread_func(name):
print("Thread " + name + " running")
t2 = threading.Thread(target=thread_func, args=("t2",))
t2.start()
在以上例子中,我们分别展示了两种方式。
第一种方式是继承Thread
类,并在类中实现run()
方法,在run()
方法中编写线程的执行任务。
第二种方式是通过定义一个线程函数,并将其作为Thread
类构造函数的参数传递,同时需要将该函数程序逻辑定义在args
参数中,如上代码中的thread_func
函数。
线程的启动与停止
启动线程只需调用Thread
对象的start()
方法即可。
import threading
def thread_func(name):
print("Thread " + name + " running")
t = threading.Thread(target=thread_func, args=("t",))
t.start()
停止线程有两种方式:
1. 通过_stop()
方法
_stop()
方法是Thread
类中自带的方法,可以用来停止线程。但需要注意的是,此方法不推荐使用,因为可能会在程序中短时间内留下一些脏数据。
import threading
import time
def thread_func():
print("Thread running")
time.sleep(3)
t = threading.Thread(target=thread_func)
t.start()
t._stop()
2. 通过标志位停止线程
可以通过设置一个标志位,来通知线程该停止了。在线程中需要做的事情是,在执行任务的过程中,判断标志位的值是否为True
,如果为False
,则终止线程。
import threading
import time
flag = True
def thread_func():
print("Thread running")
while flag:
time.sleep(0.1)
print("Thread stopped")
t = threading.Thread(target=thread_func)
t.start()
time.sleep(1)
flag = False
在以上例子中,我们定义了一个flag
变量,作为停止线程的标志位,并在thread_func
函数中使用该标志位进行判断。在主程序中,睡眠1秒后,将该标志位设置为False
即可停止线程。
示例1:线程同步
当多个线程同时访问一个共享资源时,可能会出现数据混乱,因此我们需要通过线程同步的方式来解决这个问题。
以下是一个简单的线程同步的例子:
import threading
import time
class Counter(object):
def __init__(self, count):
self.count = count
self.lock = threading.Lock()
def add(self, n):
self.lock.acquire()
self.count += n
time.sleep(1)
print("add %d, the count now is %d" % (n, self.count))
self.lock.release()
def reduce(self, n):
self.lock.acquire()
self.count -= n
time.sleep(1)
print("reduce %d, the count now is %d" % (n, self.count))
self.lock.release()
def add(c):
for i in range(5):
c.add(1)
def reduce(c):
for i in range(5):
c.reduce(1)
counter = Counter(10)
t1 = threading.Thread(target=add, args=(counter,))
t2 = threading.Thread(target=reduce, args=(counter,))
t1.start()
t2.start()
t1.join()
t2.join()
在以上例子中,我们定义了一个Counter
类,其中包含add
和reduce
两个方法,分别用于加和减。在类的成员变量中,我们使用了Lock
类,用于线程同步。在add
和reduce
方法中,使用了lock
对象对部分程序逻辑进行了阻塞,以保证线程同步。
示例2:线程池
线程池是一种可以重用线程的技术,它可以更好地控制线程的数量和生命周期。以下是一个简单的线程池的例子:
import threading
import time
class ThreadPool(object):
def __init__(self, max_threads):
self.queue = []
self.lock = threading.Lock()
self.pool = [threading.Thread(target=self.run) for i in range(max_threads)]
self.running = True
self.thread_limit = max_threads
for t in self.pool:
t.start()
def add_task(self, task):
self.lock.acquire()
self.queue.insert(0, task)
self.lock.release()
def run(self):
while self.running:
self.lock.acquire()
if len(self.queue):
task = self.queue.pop()
self.lock.release()
task()
else:
self.lock.release()
time.sleep(0.1)
def stop(self):
self.running = False
for t in self.pool:
t.join()
def func_a():
print("func_a running")
time.sleep(1)
def func_b():
print("func_b running")
time.sleep(1)
pool = ThreadPool(3)
pool.add_task(func_a)
pool.add_task(func_b)
pool.stop()
在以上例子中,我们定义了一个ThreadPool
类,使用了一个队列来存储线程任务。在类的构造函数中创建了一定数量的线程,在队列中存储多个任务。在run
方法中,使用了while
循环,不断取出队列中的任务,并执行。在stop
方法中,通过设置running
标志位为False
,停止线程池中所有线程。
最后,我们在实际应用中,可以根据自己的需求,灵活运用threading
模块中不同的方法和技巧,来实现对线程的有效管理和控制。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python线程threading模块用法详解 - Python技术站