多线程——threading和queue模块的理解。加实例+详解+思路

并发:假的多任务

并行:真的多任务

实现多线程用——threading模块

import threading
import time

def shuru():
    for i in range(1,4):
        print("正在输入")
        time.sleep(1)
def shuchu():
    for i in range(1,4):
        print("正在输出")
        time.sleep(1)

t = threading.Thread(target=shuru)
t2 = threading.Thread(target=shuchu)
t.start()
t2.start()

在遇到start时,才会运行。 (创建一个Thread不会创建一个线程)

start调用后才会创建

 

这个就是个简单的多线程,但是如果我们用,输入代表,输入网站url,输出为下载到文件。

这就是混乱的,就会不好满足。 

2.查看线程数量。

threading.enumerate()

3.传参

t2 = threading.Thread(target=shuchu,args=(10,))

args传入的是一个“元组

                                                            <指名道姓的传参>

t2 = threading.Thread(target=shuchu,kwargs={'num1':44,'num':10})

注意形式

=========================================================================

创建线程的另一种方式:(如果想要线程,线程之间共享数据,用上面的方法就会不好)

用类的方式去实现。

import threading
import time


class Task(threading.Thread):
    def run(self):
        while True:
            print("qqqq")
            time.sleep(1)
t = Task()
t.start()
print(len(threading.enumerate()))
while True:
    print("ppp")
    time.sleep(1)

可以看出有两个线程。

一但start()就会到run方法里面去——这里只会去执行run里面。想要用别的方法,就在run里面       去调用


队列(Queue)——为什么要用——就是要配合,就像,先生产,再消费。也就是说,就像提取网络图片,是先拿到网址,然后请求,然后保存的。是有先后顺序的。

可以让多个线程之间实现数据共享,可以实现先,存入,然后先出去。

1.先进先出-queue.Queue()

这里的put和get,会等待。直到有数据。没有数据时就会一直等待

import queue

list_m = queue.Queue()
list_m.put('123')
print(list_m.get())

 

存入然后打印

import queue

list_m = queue.Queue()
list_m.put('123')
list_m.put('456')
list_m.put('789')

print(list_m.get())
print(list_m.get())
print(list_m.get())

先进先出。 

2.先进后出——queue.LifoQueue()

import queue
list_m = queue.LifoQueue()
list_m.put('123')
list_m.put('456')
list_m.put('789')

print(list_m.get())
print(list_m.get())
print(list_m.get())

3.优先级—— queue.PriorityQueue()

数字越小优先级越高 

import queue
list_m = queue.PriorityQueue()
list_m.put((1,'123'))
list_m.put((7,'456'))
list_m.put((2,'789'))

print(list_m.get())
print(list_m.get())
print(list_m.get())


下来进入正题:关于多线程网站的爬取 ——BeautifulSoup+threading

 简单说一下下面代码的思路:

1.先建立,两个queue.Queue队列,用来存放url(这个是页数) 和html(这个是书名的网址) 

2.让把目录的网站都放在url队列里

3.然后再建立三个线程去,获得html,直到 url_queue.get()获取完成,机会阻塞。这个线程就停了

4.然后建立两个去保存标题

import queue
import time
import random
import threading
import requests
from bs4 import BeautifulSoup

urls = [
    f"https://www.cnblogs.com/#p{page}"
    for page in range(1,50+1)
]
def craw(url):
    r= requests.get(url)
    return r.text


def parse(html):
#class="post-item-title"
    soup = BeautifulSoup(html,'html.parser')
    links = soup.find_all('a',class_='post-item-title')
    return [(link["href"],link.get_text())for link in links]
def do_craw(url_queue:queue.Queue,html_queue:queue.Queue):
    while True:
        url = url_queue.get()
        html = craw(url)
        html_queue.put(html)
        time.sleep(random.randint(1,2))#随机的睡眠一到两秒
def do_parse(html_queue:queue.Queue,fout):
    while True:
        html = html_queue.get()
        results = parse(html)
        for result in results:
            fout.write(str(result)+"\n")
        time.sleep(random.randint(1,2))#随机的睡眠一到两秒

if __name__=="__main__":
    url_queue=queue.Queue()
    html_queue = queue.Queue()
    for url in urls:
        url_queue.put(url)
    #生产者线程
    for idx in range(3):
        t=threading.Thread(target=do_craw,args=(url_queue,html_queue))
        t.start()
    #消费者线程
    fout = open("03.data.txt","w")
    for idx in range(2):
        t=threading.Thread(target=do_parse,args=(html_queue,fout))
        t.start()

主要用到几个函数:

其中两个要去线程的函数:

1.def do_parse(html_queue:queue.Queue,fout):
2.def do_craw(url_queue:queue.Queue,html_queue:queue.Queue):

将你的线程对象给,这个函数。也就是实现了,线程之间的数据的共享

你给的其实就是列表,然后你给进去然后,一个一个get。直到get结束

 

相关推荐

  1. Queue线爬虫multiprocessing进程

    2024-02-23 14:30:01       44 阅读
  2. C#线之(Thread详解与示例

    2024-02-23 14:30:01       30 阅读
  3. 使用Python threading模块创建线程序

    2024-02-23 14:30:01       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-23 14:30:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-23 14:30:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-23 14:30:01       87 阅读
  4. Python语言-面向对象

    2024-02-23 14:30:01       96 阅读

热门阅读

  1. Flink 侧输出流(SideOutput)

    2024-02-23 14:30:01       47 阅读
  2. int128的实现(基本完成)

    2024-02-23 14:30:01       56 阅读
  3. qt creator5.15.2用的是什么版本的图形api?

    2024-02-23 14:30:01       50 阅读
  4. 【软件设计模式之迭代器与组合模式】

    2024-02-23 14:30:01       51 阅读
  5. 【OpcUA开发笔记 2】open62541在Linux下编译及Qt开发

    2024-02-23 14:30:01       49 阅读
  6. 日常leetcode代码思路总结(持续更新)

    2024-02-23 14:30:01       59 阅读
  7. 【机器学习】机器学习是什么?

    2024-02-23 14:30:01       48 阅读