爬虫13——线程进程

1、 线程进程的概述

操作系统每次运行一个程序的时候,他都会给程序准备一个内存,然后这个内存里专门放程序里面执行过程中产生的变量。

这个内存区域可以被认为是xxx进程,然后在进程里面又有若干个线程来帮我们工作(至少有一个)。所以进程是一个资源单位,而线程是执行单位,CPU在跑的时候执行的是线程。

当我们创建一个进程,如果不创建线程行不行? 答案当然是不行的,可以把进程比做一个公司,为了能让公司运行起来,必须至少有一个员工(线程),当在程序执行的时候,一个线程不够用,则需要多创建几个线程,这就是多线程的概念。

每次创建程序的时候,都有一个主线程在里面(main)

2、下面给出一个案例,观察是否为多线程程序

def func():
    for i in range(1000):
        print("func",i)
if __name__ == '__main__':
    func()
    for i in range(1000):
        print("main",i)

通过观察程序执行的过程,程序执行的时候,首先去生成func,然后在主线程里会再回到func函数去执行,执行完后再回到main里再往下执行,所以这是一根线的进程,单线程,不是多线程。

运行结果也可以看出是先执行func再执行main。

3、多线程的两种创建方法

方法一:导包Thread

# 进程,线程
# 进程是资源单位,每一个进程至少有一个线程
# 线程是执行单位

# 启动每一个程序默认都会有一个主线程

#多线程
from threading import Thread # 线程类
def func():
    for i in range(1000):
        print("func",i)

if __name__ == '__main__':
    #创建线程类对象,并告诉程序你当前的线程,如果要执行的话,要执行谁 。
    #target=后面的子线程不能加括号 加括号相当于返回值做参数,不加括号相当于函数本身做参数。
    T = Thread(target=func) #创建线程,并给线程分配任务,
    '''
    Thread相当与公司招了一个新员工,新线程
    target=func 相当于告诉新员工,如果你开始执行,你该干什么事情
    同时呢,招完员工后自己该干什么事继续去干
    '''
    T.start() #多线程的状态为可以开始工作状态,具体的执行时间还得由CPU决定
    for i in range(1000):
        print("main",i)

通过运行结果发现,func和main两个线程在一起执行,因为打印的地方都是在控制台,所以会出现重叠的过程。

方法二:自己创建类 MyThread

from threading import Thread # 线程类
class MyThread(Thread): #继承Thread
    '''
    MyThread是我们自己创建的类,我们的类继承Thread就相当于是Thread的子类
    所以我们写的类就会有Thread的特性
    (子承父业)
    '''
    # 重写Thread里的run方法
    def run(self): #当线程被执行的时候,被执行的就是run()
        for i in range(1000):
            print("子线程", i)
if __name__ == '__main__':
    T = MyThread()
    #T.run() #方法的调用 单线程
    T.start() #开启线程
    for i in range(1000):
        print("主线程",i)

运行结果也是一样的。 

4、多线程的创建(传参)

当我们需要传入两个线程的时候,如果是以下这种方法很难看出哪个是哪个。

from threading import Thread
def func():
    for i in range(1000):
        print("func",i)
if __name__ == '__main__':
    T1 = Thread(target=func)
    T1.start()

    T2 = Thread(target=func)
    T2.start()

【运行结果】

显示的都是func,并不知道t1和t2分别是哪个

这个时候就需要用到传参的方法了。 只需要在传入线程的时候,增加一个参数(args)用来确认线程的名字就可以了,需要注意的是,args对应的值必须是元组。

from threading import Thread
def func(name):
    for i in range(1000):
        print(name,i)
if __name__ == '__main__':
    T1 = Thread(target=func,args=("王力宏",)) # 传入参数必须是元组的形式
    T1.start()

    T2 = Thread(target=func,args=("周杰伦",))
    T2.start()

这样就可以很清楚的知道每个线程的名字了。 

 5、多进程的创建

相对于多线程,多进程会用到的更少一点,因为开辟进程,相对与开辟线程,所用到的资源要多的多,因为要开内存。

多进程的创建和多线程相似,只是导入的包不同

from multiprocessing import Process #进程类
def func():
    for i in range(20000):
        print("子进程",i)
if __name__ == '__main__':
    P = Process(target=func)
    P.start()
    for i in range(20000):
        print("主进程",i)

【运行结果】

猜你喜欢

转载自blog.csdn.net/m0_48936146/article/details/124748533