博客
关于我
Python 多线程学习(转)
阅读量:796 次
发布时间:2023-03-07

本文共 3182 字,大约阅读时间需要 10 分钟。

全局解释器锁(GIL)是Python解释器的核心机制,它限制了并发线程对Python对象的访问,确保线程安全。GIL每100字节码指令周期进行一次锁释放和重新获取,尽管这一机制有效防止了并发安全问题,但也限制了多线程程序的性能表现。

理解线程与进程的区别是掌握线程编程的第一步。线程与进程在资源共享方面存在根本差异:线程共享同一内存空间和资源,但各线程间的状态一致;而进程则拥有独立的内存空间和资源。线程的轻量级特性使其在资源利用上更高效,但同时也带来了竞态条件、死锁等复杂问题。

Python线程的基本使用方法可以通过以下示例来体现:

import threadingimport datetimeclass ThreadClass(threading.Thread):    def run(self):        now = datetime.datetime.now()        print(f"{self.getName()} says Hello World at time: {now}")        t1 = ThreadClass()t2 = ThreadClass()t1.start()t2.start()

输出结果显示,两个线程能够同时输出"Hello World",并带有时间戳。这个简单的示例展示了线程的基本使用方式,类ThreadClass通过继承threading.Thread创建了一个线程池,run方法定义了线程执行的操作。

线程编程的复杂性在于需要处理共享资源的安全访问。队列模块提供了一种简便的解决方案,通过将任务传递给各个线程,简化了线程间的通信与同步。在以下示例中,使用队列实现了并发访问URL的处理:

import urllib2import timeimport Queueimport threadinghosts = ["http://yahoo.com", "http://baidu.com", "http://amazon.com",        "http://ibm.com", "http://apple.com"]queue = Queue.Queue()class ThreadUrl(threading.Thread):    def __init__(self, queue):        threading.Thread.__init__(self)        self.queue = queue    def run(self):        while True:            host = self.queue.get()            url = urllib2.urlopen(host)            print(url.read(1024))            self.queue.task_done()            start = time.time()def main():    for _ in range(5):        t = ThreadUrl(queue)        t.setDaemon(True)        t.start()        for host in hosts:        queue.put(host)        queue.join()main()print(f"Elapsed Time: {time.time() - start}")

在这个示例中,主线程创建了5个守护线程池,负责处理URL请求。每个线程从队列中获取URL,处理完毕后调用task_done。主线程通过队列.join()等待所有任务完成。

线程编程的高级特性可以通过组合多个队列实现更复杂的任务流程。例如,下面的示例展示了如何将多个队列用于数据处理:

import Queueimport threadingimport urllib2from BeautifulSoup import BeautifulSouphosts = ["http://yahoo.com", "http://baidu.com", "http://amazon.com",        "http://ibm.com", "http://apple.com"]queue = Queue.Queue()out_queue = Queue.Queue()class ThreadUrl(threading.Thread):    def __init__(self, queue, out_queue):        threading.Thread.__init__(self)        self.queue = queue        self.out_queue = out_queue    def run(self):        while True:            host = self.queue.get()            url = urllib2.urlopen(host)            chunk = url.read()            self.out_queue.put(chunk)            self.queue.task_done()class DatamineThread(threading.Thread):    def __init__(self, out_queue):        threading.Thread.__init__(self)        self.out_queue = out_queue    def run(self):        while True:            chunk = self.out_queue.get()            soup = BeautifulSoup(chunk)            print(f"Found: {len(soup.findAll(['title']))} titles")            self.out_queue.task_done()def main():    for _ in range(5):        t = ThreadUrl(queue, out_queue)        t.setDaemon(True)        t.start()        for host in hosts:        queue.put(host)        for _ in range(5):        dt = DatamineThread(out_queue)        dt.setDaemon(True)        dt.start()        queue.join()    out_queue.join()main()print(f"Elapsed Time: {time.time() - start}")

在这个扩展示例中,使用了两个队列:一个用于分发URL请求,另一个用于存储和处理获取的网页内容。这种模式展示了如何通过多级队列实现任务流水线,提高了并发处理效率。

线程编程的关键在于正确管理共享资源和避免竞争条件。通过使用队列模块,可以显著降低线程编程的复杂性,实现更高效的资源利用。在实际应用中,选择线程还是进程取决于任务的特性,进程适合需要长时间运行或资源密集型任务,而线程适合需要频繁通信的轻量级任务。

转载地址:http://kiofk.baihongyu.com/

你可能感兴趣的文章
python | rpyc,一个超实用的 Python 库!
查看>>
python | rq,一个无敌的 关于Redis 的Python 库!
查看>>
python读取字符串指定位置字符_python要怎么截取指定位置的字符串呢?
查看>>
python | scikit-llm,一个神奇的 Python 库!
查看>>
python | sentry,一个超酷的 关于错误监控工具 Python 库!
查看>>
python | shiv,一个超酷的 打包工具 Python 库!
查看>>
python | six,一个神奇的 Python 库!
查看>>
Python读取图片的几种方法供net使用
查看>>
python | spacy,一个神奇的 Python 库!
查看>>
python | sqlmap,一个实用的 Python 库!
查看>>
python | sumy,一个超酷的 用于文本摘要的 Python 库!
查看>>
python | tiler,一个不可思议的 图像切片重组 Python 库!
查看>>
python | tinydb,一个非常厉害的 关于数据库的 Python 库!
查看>>
python | tox,一个超强的 自动化测试工具 Python 库!
查看>>
python | ttkbootstrap,一个神奇的 Python 库!
查看>>
python | unoconv,一个超厉害的 Python 库!
查看>>
python | urllib3,一个超强的 Python 库!
查看>>
python | webassets,一个超强的 Python 库!
查看>>
python | werkzeug,一个不可思议的 Python 库!
查看>>
python | xlsxwriter,一个实用的 Python 库!
查看>>