多任务、线程理解

多任务及线程的创建

1.先谈多任务,假如没有多任务,那就只能执行完一个任务再去执行一个任务。

先看代码:

import time
import threading
def sing():
    for i in range(1,5):
        print("%s在唱歌"%i)
    print("sing end-----")
def dance():
    for i in range(1,5):
        print("%s在跳舞" % i)
    print("dance end-------")

if __name__ == '__main__':
    sing()
    dance()

结果:

其实,正常的情况下应该边唱歌边跳舞。

2.多任务实现线程:

当为单核cpu的时候,其实是假的多任务,看似同时执行。其实一种方法是通过操作系统调度,让任务的切换时间足够快,让用户认为几乎是在同一时间执行的。另外一种方法为优先级调度,它对时间的要求不严格。

多任务涉及两个概念:并行和并发,解释一下,并行指的是cpu的核数大于任务数,并发是指cpu核数小于任务数。

线程

  • 一个程序运行起来后,一定有一个执行代码的东西,这个东西就是线程。
  • 线程运行没有顺序。
  • 当创建的子线程所执行的函数结束,那么意味着这个子线程结束。
  • 如果创建的主线程死掉,那么子线程一定会死掉。

1.如何查看线程的数量

threading.enumerate()

threading.enumerate()返回的是一个列表,包括主线程

调用thread,但没有执行start()方法那么仅仅是创建了一个对象,只有调用start()方法时,才会创建线程,以及让线程开始运行。

2.创建线程的方式

  • 使用threading.Thread(target=函数名,args=(元组参数))
  • 创建线程类,继承threading.Thread,且必须包含run()方法。当一个线程做的事情比较复杂的时候,而且需要分成多个函数来实现功能。例如层级爬取数据可以考虑使用创建线程类。

上代码1(使用threading.Thread):

import time
import threading
def sing():
    for i in range(1,5):

        print("%s在唱歌"%i)
        # time.sleep(1)
    print("sing end-----")
def dance():
    for i in range(1,5):
        print("%s在跳舞" % i)
        # time.sleep(1)
    print("dance end-------")

if __name__ == '__main__':
    start=time.time()
    sing()
    dance()
     t1=threading.Thread(target=sing)
     t2=threading.Thread(target=dance)
     t1.start()
     end=time.time()
     print('time is %s'%(start-end))
     while True:
         length=len(threading.enumerate())
         print("当前运行的线程为:%d"%length)
         if length<=1:
            break
         print(threading.enumerate())
         time.sleep(1)

代码2(创建线程类)爬取腾讯招聘:

import json
import time
import requests
import threading
from queue import Queue

class Tecentthead(threading.Thread):
    def __init__(self,i,page_queue):
        super().__init__()
        self.i=i
        self.page_queue=page_queue
    def run(self):
        #线程不能执行一个任务就退出,需要不断取任务
        # 所以可以通过队列是否为空来保证任务都被执行
        while True:
            #任务停止条件,当任务为空时,线程退出
            if self.page_queue.empty():
                break
            page = page_queue.get()
            print("===================线程{}开始执行任务{}================".format(self.i, page))

            url='https://careers.tencent.com/tencentcareer/api/post/Query?keyword=python&pageIndex={}&pageSize=10'.format(page)
            self.get_info(url)
            print("===================线程{}执行任务{}结束================".format(self.i,page))
    #1.请求接口数据
    def get_info(self,url):
        headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'}
        response = requests.get(url=url, headers=headers).text
        # with open('tecent.json','w',encoding='utf-8')as f :
        #     f.write(response)
        self.parse(response)
    #2.解析接口数据
    def parse(self,response):
        response = json.loads(response)
        # print(type(response))
        joblist = response["Data"]["Posts"]
        for i in joblist:
            name = i["RecruitPostName"]
            LocationName = i["LocationName"]
            Responsibility = i["Responsibility"].replace("\n", "").replace("\r", "")
            PostURL = i["PostURL"]
            info = "职位:{},工作地点{},职责:{},链接:{}".format(name, LocationName, Responsibility, PostURL)
            with open('job1.txt', 'a', encoding='utf-8')as f:
                f.write(info + "\n")
if __name__ == '__main__':
    #主进程的任务就是启动线程开关,并不担心任务执行过程。
    start_time=time.time()
    print("============主线程开始,时间为{}===============".format(start_time))
    #1.创建任务队列
    page_queue=Queue()
    for page in range(1,10):
        page_queue.put(page)
    #2.起线程任务,规定3个线程
    threadjob_list=['c1','c2','c3']
    #3.创建任务队列,用来阻塞主线程的结束
    job_list=[]
    for i in threadjob_list:
        t=Tecentthead(i,page_queue)
        t.start()
        job_list.append(t)
    #循环遍历任务队列,阻塞主进程的结束,等任务队列中的所有任务结束之后
    #主进程最后结束。join的主要作用就是阻塞主进程的结束,优先执行自己。
    for k in job_list:
        k.join()
    end_time=time.time()
    print("============主线程结束,耗时为{}===============".format(end_time-start_time))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值